| .. | .. |
|---|
| 33 | 33 | */ |
|---|
| 34 | 34 | |
|---|
| 35 | 35 | #include <linux/clk.h> |
|---|
| 36 | +#include <linux/compat.h> |
|---|
| 36 | 37 | #include <linux/iopoll.h> |
|---|
| 37 | 38 | #include <linux/pm_runtime.h> |
|---|
| 38 | 39 | #include <linux/regmap.h> |
|---|
| .. | .. |
|---|
| 42 | 43 | #include <linux/kfifo.h> |
|---|
| 43 | 44 | #include <linux/interrupt.h> |
|---|
| 44 | 45 | #include <linux/rk-preisp.h> |
|---|
| 45 | | -#include <linux/rkisp21-config.h> |
|---|
| 46 | +#include <linux/rk-isp21-config.h> |
|---|
| 46 | 47 | #include <linux/iommu.h> |
|---|
| 47 | 48 | #include <media/v4l2-event.h> |
|---|
| 48 | 49 | #include <media/media-entity.h> |
|---|
| 49 | 50 | |
|---|
| 50 | 51 | #include "common.h" |
|---|
| 52 | +#include "isp_external.h" |
|---|
| 51 | 53 | #include "regs.h" |
|---|
| 52 | 54 | #include "rkisp_tb_helper.h" |
|---|
| 53 | 55 | |
|---|
| .. | .. |
|---|
| 82 | 84 | * | +---------------------------------------------------+ | |
|---|
| 83 | 85 | * +---------------------------------------------------------+ |
|---|
| 84 | 86 | */ |
|---|
| 87 | + |
|---|
| 88 | +static void rkisp_config_cmsk(struct rkisp_device *dev); |
|---|
| 85 | 89 | |
|---|
| 86 | 90 | struct backup_reg { |
|---|
| 87 | 91 | const u32 base; |
|---|
| .. | .. |
|---|
| 188 | 192 | u32 code = dev->isp_sdev.in_frm.code; |
|---|
| 189 | 193 | u32 src_w = dev->isp_sdev.in_frm.width; |
|---|
| 190 | 194 | u32 src_h = dev->isp_sdev.in_frm.height; |
|---|
| 191 | | - u32 dest_w, dest_h, w, h; |
|---|
| 195 | + u32 dest_w, dest_h, w, h, max_size, max_h, max_w; |
|---|
| 192 | 196 | int ret = 0; |
|---|
| 193 | 197 | |
|---|
| 194 | 198 | if (!crop) |
|---|
| 195 | 199 | return -EINVAL; |
|---|
| 196 | 200 | |
|---|
| 197 | | - if (dev->isp_ver == ISP_V12) { |
|---|
| 198 | | - w = clamp_t(u32, src_w, |
|---|
| 199 | | - CIF_ISP_INPUT_W_MIN, |
|---|
| 200 | | - CIF_ISP_INPUT_W_MAX_V12); |
|---|
| 201 | | - h = clamp_t(u32, src_h, |
|---|
| 202 | | - CIF_ISP_INPUT_H_MIN, |
|---|
| 203 | | - CIF_ISP_INPUT_H_MAX_V12); |
|---|
| 204 | | - } else if (dev->isp_ver == ISP_V13) { |
|---|
| 205 | | - w = clamp_t(u32, src_w, |
|---|
| 206 | | - CIF_ISP_INPUT_W_MIN, |
|---|
| 207 | | - CIF_ISP_INPUT_W_MAX_V13); |
|---|
| 208 | | - h = clamp_t(u32, src_h, |
|---|
| 209 | | - CIF_ISP_INPUT_H_MIN, |
|---|
| 210 | | - CIF_ISP_INPUT_H_MAX_V13); |
|---|
| 211 | | - } else if (dev->isp_ver == ISP_V21) { |
|---|
| 212 | | - w = clamp_t(u32, src_w, |
|---|
| 213 | | - CIF_ISP_INPUT_W_MIN, |
|---|
| 214 | | - CIF_ISP_INPUT_W_MAX_V21); |
|---|
| 215 | | - h = clamp_t(u32, src_h, |
|---|
| 216 | | - CIF_ISP_INPUT_H_MIN, |
|---|
| 217 | | - CIF_ISP_INPUT_H_MAX_V21); |
|---|
| 218 | | - } else { |
|---|
| 219 | | - w = clamp_t(u32, src_w, |
|---|
| 220 | | - CIF_ISP_INPUT_W_MIN, |
|---|
| 221 | | - CIF_ISP_INPUT_W_MAX); |
|---|
| 222 | | - h = clamp_t(u32, src_h, |
|---|
| 223 | | - CIF_ISP_INPUT_H_MIN, |
|---|
| 224 | | - CIF_ISP_INPUT_H_MAX); |
|---|
| 201 | + memset(&sel, 0, sizeof(sel)); |
|---|
| 202 | + switch (dev->isp_ver) { |
|---|
| 203 | + case ISP_V12: |
|---|
| 204 | + max_w = CIF_ISP_INPUT_W_MAX_V12; |
|---|
| 205 | + max_h = CIF_ISP_INPUT_H_MAX_V12; |
|---|
| 206 | + break; |
|---|
| 207 | + case ISP_V13: |
|---|
| 208 | + max_w = CIF_ISP_INPUT_W_MAX_V13; |
|---|
| 209 | + max_h = CIF_ISP_INPUT_H_MAX_V13; |
|---|
| 210 | + break; |
|---|
| 211 | + case ISP_V21: |
|---|
| 212 | + max_w = CIF_ISP_INPUT_W_MAX_V21; |
|---|
| 213 | + max_h = CIF_ISP_INPUT_H_MAX_V21; |
|---|
| 214 | + break; |
|---|
| 215 | + case ISP_V30: |
|---|
| 216 | + if (dev->hw_dev->is_unite) { |
|---|
| 217 | + max_w = CIF_ISP_INPUT_W_MAX_V30_UNITE; |
|---|
| 218 | + max_h = CIF_ISP_INPUT_H_MAX_V30_UNITE; |
|---|
| 219 | + } else { |
|---|
| 220 | + max_w = CIF_ISP_INPUT_W_MAX_V30; |
|---|
| 221 | + max_h = CIF_ISP_INPUT_H_MAX_V30; |
|---|
| 222 | + } |
|---|
| 223 | + break; |
|---|
| 224 | + case ISP_V32: |
|---|
| 225 | + max_w = CIF_ISP_INPUT_W_MAX_V32; |
|---|
| 226 | + max_h = CIF_ISP_INPUT_H_MAX_V32; |
|---|
| 227 | + break; |
|---|
| 228 | + case ISP_V32_L: |
|---|
| 229 | + max_w = CIF_ISP_INPUT_W_MAX_V32_L; |
|---|
| 230 | + max_h = CIF_ISP_INPUT_H_MAX_V32_L; |
|---|
| 231 | + break; |
|---|
| 232 | + default: |
|---|
| 233 | + max_w = CIF_ISP_INPUT_W_MAX; |
|---|
| 234 | + max_h = CIF_ISP_INPUT_H_MAX; |
|---|
| 225 | 235 | } |
|---|
| 236 | + max_size = max_w * max_h; |
|---|
| 237 | + w = clamp_t(u32, src_w, CIF_ISP_INPUT_W_MIN, max_w); |
|---|
| 238 | + max_h = max_size / w; |
|---|
| 239 | + h = clamp_t(u32, src_h, CIF_ISP_INPUT_H_MIN, max_h); |
|---|
| 226 | 240 | |
|---|
| 227 | 241 | if (dev->active_sensor) |
|---|
| 228 | 242 | sensor = dev->active_sensor->sd; |
|---|
| .. | .. |
|---|
| 343 | 357 | return -ENODEV; |
|---|
| 344 | 358 | |
|---|
| 345 | 359 | sensor = sd_to_sensor(dev, sensor_sd); |
|---|
| 346 | | - ret = v4l2_subdev_call(sensor->sd, video, g_mbus_config, |
|---|
| 347 | | - &sensor->mbus); |
|---|
| 360 | + if (!sensor) |
|---|
| 361 | + return -ENODEV; |
|---|
| 362 | + ret = v4l2_subdev_call(sensor->sd, pad, get_mbus_config, |
|---|
| 363 | + 0, &sensor->mbus); |
|---|
| 348 | 364 | if (ret && ret != -ENOIOCTLCMD) |
|---|
| 349 | 365 | return ret; |
|---|
| 350 | 366 | |
|---|
| 351 | | - if (sensor->mbus.type == V4L2_MBUS_CSI2) { |
|---|
| 367 | + sensor->fmt[0].pad = 0; |
|---|
| 368 | + sensor->fmt[0].which = V4L2_SUBDEV_FORMAT_ACTIVE; |
|---|
| 369 | + ret = v4l2_subdev_call(sensor->sd, pad, get_fmt, |
|---|
| 370 | + &sensor->cfg, &sensor->fmt[0]); |
|---|
| 371 | + if (ret && ret != -ENOIOCTLCMD) |
|---|
| 372 | + return ret; |
|---|
| 373 | + |
|---|
| 374 | + if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY && |
|---|
| 375 | + dev->isp_ver < ISP_V30) { |
|---|
| 352 | 376 | u8 vc = 0; |
|---|
| 353 | 377 | |
|---|
| 354 | | - memset(dev->csi_dev.mipi_di, 0, |
|---|
| 355 | | - sizeof(dev->csi_dev.mipi_di)); |
|---|
| 356 | | - memset(sensor->fmt, 0, sizeof(sensor->fmt)); |
|---|
| 378 | + sensor_sd = get_remote_sensor(sensor->sd); |
|---|
| 379 | + if (!sensor_sd) |
|---|
| 380 | + return -ENODEV; |
|---|
| 381 | + memset(dev->csi_dev.mipi_di, 0, sizeof(dev->csi_dev.mipi_di)); |
|---|
| 357 | 382 | for (i = 0; i < dev->csi_dev.max_pad - 1; i++) { |
|---|
| 383 | + struct rkmodule_channel_info ch = { 0 }; |
|---|
| 384 | + |
|---|
| 358 | 385 | fmt = &sensor->fmt[i]; |
|---|
| 359 | | - fmt->pad = i; |
|---|
| 360 | | - fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE; |
|---|
| 361 | | - ret = v4l2_subdev_call(sensor->sd, pad, get_fmt, |
|---|
| 362 | | - &sensor->cfg, fmt); |
|---|
| 363 | | - if (ret && ret != -ENOIOCTLCMD) |
|---|
| 364 | | - return ret; |
|---|
| 386 | + ch.index = i; |
|---|
| 387 | + ret = v4l2_subdev_call(sensor_sd, core, ioctl, |
|---|
| 388 | + RKMODULE_GET_CHANNEL_INFO, &ch); |
|---|
| 389 | + if (ret) { |
|---|
| 390 | + if (i) |
|---|
| 391 | + *fmt = sensor->fmt[0]; |
|---|
| 392 | + } else { |
|---|
| 393 | + fmt->format.width = ch.width; |
|---|
| 394 | + fmt->format.height = ch.height; |
|---|
| 395 | + fmt->format.code = ch.bus_fmt; |
|---|
| 396 | + } |
|---|
| 365 | 397 | ret = mbus_pixelcode_to_mipi_dt(fmt->format.code); |
|---|
| 366 | 398 | if (ret < 0) { |
|---|
| 367 | 399 | v4l2_err(&dev->v4l2_dev, |
|---|
| 368 | 400 | "Invalid mipi data type\n"); |
|---|
| 369 | 401 | return ret; |
|---|
| 370 | 402 | } |
|---|
| 371 | | - /* v4l2_subdev_format reserved[0] |
|---|
| 372 | | - * using as mipi virtual channel |
|---|
| 373 | | - */ |
|---|
| 374 | | - switch (fmt->reserved[0]) { |
|---|
| 403 | + |
|---|
| 404 | + switch (ch.vc) { |
|---|
| 375 | 405 | case V4L2_MBUS_CSI2_CHANNEL_3: |
|---|
| 376 | 406 | vc = 3; |
|---|
| 377 | 407 | break; |
|---|
| .. | .. |
|---|
| 393 | 423 | fmt->format.width, |
|---|
| 394 | 424 | fmt->format.height); |
|---|
| 395 | 425 | } |
|---|
| 396 | | - } else { |
|---|
| 397 | | - sensor->fmt[0].pad = 0; |
|---|
| 398 | | - sensor->fmt[0].which = V4L2_SUBDEV_FORMAT_ACTIVE; |
|---|
| 399 | | - ret = v4l2_subdev_call(sensor->sd, pad, get_fmt, |
|---|
| 400 | | - &sensor->cfg, &sensor->fmt[0]); |
|---|
| 401 | | - if (ret && ret != -ENOIOCTLCMD) |
|---|
| 402 | | - return ret; |
|---|
| 403 | 426 | } |
|---|
| 404 | 427 | |
|---|
| 405 | 428 | v4l2_subdev_call(sensor->sd, video, g_frame_interval, &sensor->fi); |
|---|
| 406 | 429 | dev->active_sensor = sensor; |
|---|
| 407 | | - |
|---|
| 430 | + i = dev->dev_id; |
|---|
| 431 | + if (sensor->fi.interval.numerator) |
|---|
| 432 | + dev->hw_dev->isp_size[i].fps = |
|---|
| 433 | + sensor->fi.interval.denominator / sensor->fi.interval.numerator; |
|---|
| 408 | 434 | return ret; |
|---|
| 409 | 435 | } |
|---|
| 410 | 436 | |
|---|
| .. | .. |
|---|
| 471 | 497 | return pixelformat; |
|---|
| 472 | 498 | } |
|---|
| 473 | 499 | |
|---|
| 500 | +static void rkisp_dvfs(struct rkisp_device *dev) |
|---|
| 501 | +{ |
|---|
| 502 | + struct rkisp_hw_dev *hw = dev->hw_dev; |
|---|
| 503 | + u64 data_rate = 0; |
|---|
| 504 | + int i, fps, num = 0; |
|---|
| 505 | + |
|---|
| 506 | + if (!hw->is_dvfs) |
|---|
| 507 | + return; |
|---|
| 508 | + hw->is_dvfs = false; |
|---|
| 509 | + for (i = 0; i < hw->dev_num; i++) { |
|---|
| 510 | + if (!hw->isp_size[i].is_on) |
|---|
| 511 | + continue; |
|---|
| 512 | + fps = hw->isp_size[i].fps; |
|---|
| 513 | + if (!fps) |
|---|
| 514 | + fps = 30; |
|---|
| 515 | + data_rate += (fps * hw->isp_size[i].size); |
|---|
| 516 | + num++; |
|---|
| 517 | + } |
|---|
| 518 | + do_div(data_rate, 1000 * 1000); |
|---|
| 519 | + /* increase margin: 25% * num */ |
|---|
| 520 | + data_rate += (data_rate >> 2) * num; |
|---|
| 521 | + |
|---|
| 522 | + /* compare with isp clock adjustment table */ |
|---|
| 523 | + for (i = 0; i < hw->num_clk_rate_tbl; i++) |
|---|
| 524 | + if (data_rate <= hw->clk_rate_tbl[i].clk_rate) |
|---|
| 525 | + break; |
|---|
| 526 | + if (i == hw->num_clk_rate_tbl) |
|---|
| 527 | + i--; |
|---|
| 528 | + |
|---|
| 529 | + /* set isp clock rate */ |
|---|
| 530 | + rkisp_set_clk_rate(hw->clks[0], hw->clk_rate_tbl[i].clk_rate * 1000000UL); |
|---|
| 531 | + if (hw->is_unite) |
|---|
| 532 | + rkisp_set_clk_rate(hw->clks[5], hw->clk_rate_tbl[i].clk_rate * 1000000UL); |
|---|
| 533 | + /* aclk equal to core clk */ |
|---|
| 534 | + if (dev->isp_ver == ISP_V32) |
|---|
| 535 | + rkisp_set_clk_rate(hw->clks[1], hw->clk_rate_tbl[i].clk_rate * 1000000UL); |
|---|
| 536 | + dev_info(hw->dev, "set isp clk = %luHz\n", clk_get_rate(hw->clks[0])); |
|---|
| 537 | +} |
|---|
| 538 | + |
|---|
| 539 | +static void rkisp_multi_overflow_hdl(struct rkisp_device *dev, bool on) |
|---|
| 540 | +{ |
|---|
| 541 | + struct rkisp_hw_dev *hw = dev->hw_dev; |
|---|
| 542 | + |
|---|
| 543 | + if (on) { |
|---|
| 544 | + /* enable bay3d and mi */ |
|---|
| 545 | + rkisp_update_regs(dev, ISP3X_MI_WR_CTRL, ISP3X_MI_WR_CTRL); |
|---|
| 546 | + rkisp_update_regs(dev, ISP3X_ISP_CTRL1, ISP3X_ISP_CTRL1); |
|---|
| 547 | + if (dev->isp_ver == ISP_V21) { |
|---|
| 548 | + rkisp_update_regs(dev, ISP21_BAY3D_CTRL, ISP21_BAY3D_CTRL); |
|---|
| 549 | + } else if (dev->isp_ver == ISP_V30) { |
|---|
| 550 | + rkisp_update_regs(dev, ISP3X_MPFBC_CTRL, ISP3X_MPFBC_CTRL); |
|---|
| 551 | + rkisp_update_regs(dev, ISP3X_MI_BP_WR_CTRL, ISP3X_MI_BP_WR_CTRL); |
|---|
| 552 | + rkisp_update_regs(dev, ISP3X_BAY3D_CTRL, ISP3X_BAY3D_CTRL); |
|---|
| 553 | + rkisp_update_regs(dev, ISP3X_SWS_CFG, ISP3X_SWS_CFG); |
|---|
| 554 | + } else if (dev->isp_ver == ISP_V32) { |
|---|
| 555 | + rkisp_update_regs(dev, ISP3X_MI_BP_WR_CTRL, ISP3X_MI_BP_WR_CTRL); |
|---|
| 556 | + rkisp_update_regs(dev, ISP32_MI_BPDS_WR_CTRL, ISP32_MI_BPDS_WR_CTRL); |
|---|
| 557 | + rkisp_update_regs(dev, ISP32_MI_MPDS_WR_CTRL, ISP32_MI_MPDS_WR_CTRL); |
|---|
| 558 | + rkisp_update_regs(dev, ISP3X_BAY3D_CTRL, ISP3X_BAY3D_CTRL); |
|---|
| 559 | + } |
|---|
| 560 | + } else { |
|---|
| 561 | + /* disabled bay3d and mi. rv1106 sdmmc workaround, 3a_wr no close */ |
|---|
| 562 | + writel(CIF_MI_CTRL_INIT_OFFSET_EN | CIF_MI_CTRL_INIT_BASE_EN, |
|---|
| 563 | + hw->base_addr + ISP3X_MI_WR_CTRL); |
|---|
| 564 | + if (dev->isp_ver == ISP_V21) { |
|---|
| 565 | + writel(0, hw->base_addr + ISP21_BAY3D_CTRL); |
|---|
| 566 | + } else if (dev->isp_ver == ISP_V30) { |
|---|
| 567 | + writel(0, hw->base_addr + ISP3X_MPFBC_CTRL); |
|---|
| 568 | + writel(0, hw->base_addr + ISP3X_MI_BP_WR_CTRL); |
|---|
| 569 | + writel(0, hw->base_addr + ISP3X_BAY3D_CTRL); |
|---|
| 570 | + writel(0xc, hw->base_addr + ISP3X_SWS_CFG); |
|---|
| 571 | + if (hw->is_unite) { |
|---|
| 572 | + writel(0, hw->base_next_addr + ISP3X_MI_WR_CTRL); |
|---|
| 573 | + writel(0, hw->base_next_addr + ISP3X_MPFBC_CTRL); |
|---|
| 574 | + writel(0, hw->base_next_addr + ISP3X_MI_BP_WR_CTRL); |
|---|
| 575 | + writel(0, hw->base_next_addr + ISP3X_BAY3D_CTRL); |
|---|
| 576 | + writel(0xc, hw->base_next_addr + ISP3X_SWS_CFG); |
|---|
| 577 | + } |
|---|
| 578 | + } else if (dev->isp_ver == ISP_V32) { |
|---|
| 579 | + writel(0, hw->base_addr + ISP3X_MI_BP_WR_CTRL); |
|---|
| 580 | + writel(0, hw->base_addr + ISP32_MI_BPDS_WR_CTRL); |
|---|
| 581 | + writel(0, hw->base_addr + ISP32_MI_MPDS_WR_CTRL); |
|---|
| 582 | + writel(0, hw->base_addr + ISP3X_BAY3D_CTRL); |
|---|
| 583 | + } |
|---|
| 584 | + } |
|---|
| 585 | + rkisp_unite_write(dev, ISP3X_MI_WR_INIT, CIF_MI_INIT_SOFT_UPD, true, hw->is_unite); |
|---|
| 586 | +} |
|---|
| 474 | 587 | |
|---|
| 475 | 588 | /* |
|---|
| 476 | 589 | * for hdr read back mode, rawrd read back data |
|---|
| .. | .. |
|---|
| 479 | 592 | void rkisp_trigger_read_back(struct rkisp_device *dev, u8 dma2frm, u32 mode, bool is_try) |
|---|
| 480 | 593 | { |
|---|
| 481 | 594 | struct rkisp_isp_params_vdev *params_vdev = &dev->params_vdev; |
|---|
| 595 | + struct rkisp_isp_stats_vdev *stats_vdev = &dev->stats_vdev; |
|---|
| 482 | 596 | struct rkisp_hw_dev *hw = dev->hw_dev; |
|---|
| 483 | 597 | u32 val, cur_frame_id, tmp, rd_mode; |
|---|
| 484 | 598 | u64 iq_feature = hw->iq_feature; |
|---|
| .. | .. |
|---|
| 488 | 602 | hw->cur_dev_id = dev->dev_id; |
|---|
| 489 | 603 | rkisp_dmarx_get_frame(dev, &cur_frame_id, NULL, NULL, true); |
|---|
| 490 | 604 | |
|---|
| 605 | + if (hw->is_multi_overflow && is_try) |
|---|
| 606 | + goto run_next; |
|---|
| 607 | + |
|---|
| 491 | 608 | val = 0; |
|---|
| 492 | | - if (mode & T_START_X1) { |
|---|
| 609 | + if (mode & (T_START_X1 | T_START_C)) { |
|---|
| 493 | 610 | rd_mode = HDR_RDBK_FRAME1; |
|---|
| 494 | 611 | } else if (mode & T_START_X2) { |
|---|
| 495 | 612 | rd_mode = HDR_RDBK_FRAME2; |
|---|
| .. | .. |
|---|
| 502 | 619 | val = rkisp_read(dev, ISP_HDRMGE_BASE, false) & 0xf; |
|---|
| 503 | 620 | } |
|---|
| 504 | 621 | |
|---|
| 622 | + if (mode & T_START_C) |
|---|
| 623 | + rkisp_expander_config(dev, NULL, true); |
|---|
| 624 | + else |
|---|
| 625 | + rkisp_expander_config(dev, NULL, false); |
|---|
| 626 | + |
|---|
| 505 | 627 | if (is_feature_on) { |
|---|
| 506 | 628 | if ((ISP2X_MODULE_HDRMGE & ~iq_feature) && (val & SW_HDRMGE_EN)) { |
|---|
| 507 | 629 | v4l2_err(&dev->v4l2_dev, "hdrmge is not supported\n"); |
|---|
| .. | .. |
|---|
| 509 | 631 | } |
|---|
| 510 | 632 | } |
|---|
| 511 | 633 | |
|---|
| 512 | | - tmp = rkisp_read(dev, ISP_HDRMGE_BASE, false) & 0xf; |
|---|
| 513 | | - if (val != tmp) { |
|---|
| 514 | | - rkisp_write(dev, ISP_HDRMGE_BASE, val, false); |
|---|
| 634 | + if (rd_mode != dev->rd_mode) { |
|---|
| 635 | + rkisp_unite_set_bits(dev, ISP_HDRMGE_BASE, ISP_HDRMGE_MODE_MASK, |
|---|
| 636 | + val, false, hw->is_unite); |
|---|
| 515 | 637 | dev->skip_frame = 2; |
|---|
| 516 | 638 | is_upd = true; |
|---|
| 517 | 639 | } |
|---|
| 518 | 640 | |
|---|
| 519 | 641 | if (dev->isp_ver == ISP_V20 && dev->dmarx_dev.trigger == T_MANUAL && !is_try) { |
|---|
| 520 | | - if (dev->rd_mode != rd_mode && RKMODULE_EXTEND_LINE != 0) { |
|---|
| 642 | + if (dev->rd_mode != rd_mode && dev->br_dev.en) { |
|---|
| 521 | 643 | tmp = dev->isp_sdev.in_crop.height; |
|---|
| 522 | 644 | val = rkisp_read(dev, CIF_DUAL_CROP_CTRL, false); |
|---|
| 523 | 645 | if (rd_mode == HDR_RDBK_FRAME1) { |
|---|
| 524 | | - val |= CIF_DUAL_CROP_MP_MODE_YUV | CIF_DUAL_CROP_SP_MODE_YUV; |
|---|
| 646 | + val |= CIF_DUAL_CROP_MP_MODE_YUV; |
|---|
| 525 | 647 | tmp += RKMODULE_EXTEND_LINE; |
|---|
| 526 | 648 | } else { |
|---|
| 527 | | - val &= ~(CIF_DUAL_CROP_MP_MODE_YUV | CIF_DUAL_CROP_SP_MODE_YUV); |
|---|
| 649 | + val &= ~CIF_DUAL_CROP_MP_MODE_YUV; |
|---|
| 528 | 650 | } |
|---|
| 529 | | - val |= CIF_DUAL_CROP_CFG_UPD; |
|---|
| 530 | 651 | rkisp_write(dev, CIF_DUAL_CROP_CTRL, val, false); |
|---|
| 531 | 652 | rkisp_write(dev, CIF_ISP_ACQ_V_SIZE, tmp, false); |
|---|
| 532 | 653 | rkisp_write(dev, CIF_ISP_OUT_V_SIZE, tmp, false); |
|---|
| .. | .. |
|---|
| 541 | 662 | rkisp_params_first_cfg(&dev->params_vdev, &dev->isp_sdev.in_fmt, |
|---|
| 542 | 663 | dev->isp_sdev.quantization); |
|---|
| 543 | 664 | rkisp_params_cfg(params_vdev, cur_frame_id); |
|---|
| 544 | | - |
|---|
| 665 | + rkisp_config_cmsk(dev); |
|---|
| 666 | + rkisp_stream_frame_start(dev, 0); |
|---|
| 545 | 667 | if (!hw->is_single && !is_try) { |
|---|
| 668 | + /* multi sensor need to reset isp resize mode if scale up */ |
|---|
| 669 | + val = 0; |
|---|
| 670 | + if (rkisp_read(dev, ISP3X_MAIN_RESIZE_CTRL, true) & 0xf0) |
|---|
| 671 | + val |= BIT(3); |
|---|
| 672 | + if (dev->isp_ver != ISP_V32_L && |
|---|
| 673 | + rkisp_read(dev, ISP3X_SELF_RESIZE_CTRL, true) & 0xf0) |
|---|
| 674 | + val |= BIT(4); |
|---|
| 675 | + if (rkisp_read(dev, ISP32_BP_RESIZE_CTRL, true) & 0xf0) |
|---|
| 676 | + val |= BIT(12); |
|---|
| 677 | + if (val) { |
|---|
| 678 | + writel(val, hw->base_addr + CIF_IRCL); |
|---|
| 679 | + writel(0, hw->base_addr + CIF_IRCL); |
|---|
| 680 | + } |
|---|
| 681 | + |
|---|
| 546 | 682 | rkisp_update_regs(dev, CTRL_VI_ISP_PATH, SUPER_IMP_COLOR_CR); |
|---|
| 547 | | - rkisp_update_regs(dev, DUAL_CROP_M_H_OFFS, DUAL_CROP_S_V_SIZE); |
|---|
| 548 | | - rkisp_update_regs(dev, ISP_ACQ_PROP, DUAL_CROP_CTRL); |
|---|
| 549 | | - rkisp_update_regs(dev, MAIN_RESIZE_SCALE_HY, MI_WR_CTRL); |
|---|
| 550 | | - rkisp_update_regs(dev, SELF_RESIZE_SCALE_HY, MAIN_RESIZE_CTRL); |
|---|
| 551 | | - rkisp_update_regs(dev, ISP_GAMMA_OUT_CTRL, SELF_RESIZE_CTRL); |
|---|
| 683 | + rkisp_update_regs(dev, DUAL_CROP_M_H_OFFS, ISP3X_DUAL_CROP_FBC_V_SIZE); |
|---|
| 684 | + rkisp_update_regs(dev, ISP_ACQ_H_OFFS, DUAL_CROP_CTRL); |
|---|
| 685 | + rkisp_update_regs(dev, SELF_RESIZE_SCALE_HY, MI_WR_CTRL); |
|---|
| 686 | + rkisp_update_regs(dev, ISP32_BP_RESIZE_SCALE_HY, SELF_RESIZE_CTRL); |
|---|
| 687 | + rkisp_update_regs(dev, MAIN_RESIZE_SCALE_HY, ISP32_BP_RESIZE_CTRL); |
|---|
| 688 | + rkisp_update_regs(dev, ISP_GAMMA_OUT_CTRL, MAIN_RESIZE_CTRL); |
|---|
| 552 | 689 | rkisp_update_regs(dev, MI_RD_CTRL2, ISP_LSC_CTRL); |
|---|
| 553 | | - rkisp_update_regs(dev, MI_MP_WR_Y_BASE, MI_MP_WR_Y_LLENGTH); |
|---|
| 690 | + rkisp_update_regs(dev, MI_MP_WR_Y_BASE, MI_WR_CTRL2 - 4); |
|---|
| 554 | 691 | rkisp_update_regs(dev, ISP_LSC_XGRAD_01, ISP_RAWAWB_RAM_DATA); |
|---|
| 555 | 692 | if (dev->isp_ver == ISP_V20 && |
|---|
| 556 | 693 | (rkisp_read(dev, ISP_DHAZ_CTRL, false) & ISP_DHAZ_ENMUX || |
|---|
| .. | .. |
|---|
| 560 | 697 | val = rkisp_read(dev, MI_WR_CTRL2, false); |
|---|
| 561 | 698 | rkisp_set_bits(dev, MI_WR_CTRL2, 0, val, true); |
|---|
| 562 | 699 | rkisp_write(dev, MI_WR_INIT, ISP21_SP_FORCE_UPD | ISP21_MP_FORCE_UPD, true); |
|---|
| 563 | | - /* sensor mode & index */ |
|---|
| 700 | + } else { |
|---|
| 701 | + if (dev->isp_ver == ISP_V32_L) |
|---|
| 702 | + rkisp_write(dev, ISP32_SELF_SCALE_UPDATE, ISP32_SCALE_FORCE_UPD, true); |
|---|
| 703 | + rkisp_unite_write(dev, ISP3X_MI_WR_INIT, CIF_MI_INIT_SOFT_UPD, true, hw->is_unite); |
|---|
| 704 | + } |
|---|
| 705 | + /* sensor mode & index */ |
|---|
| 706 | + if (dev->isp_ver >= ISP_V21) { |
|---|
| 564 | 707 | val = rkisp_read_reg_cache(dev, ISP_ACQ_H_OFFS); |
|---|
| 565 | | - val |= ISP21_SENSOR_MODE(hw->dev_num >= 3 ? 2 : hw->dev_num - 1) | |
|---|
| 566 | | - ISP21_SENSOR_INDEX(dev->dev_id); |
|---|
| 708 | + val |= ISP21_SENSOR_INDEX(dev->multi_index); |
|---|
| 709 | + if (dev->isp_ver == ISP_V32_L) |
|---|
| 710 | + val |= ISP32L_SENSOR_MODE(dev->multi_mode); |
|---|
| 711 | + else |
|---|
| 712 | + val |= ISP21_SENSOR_MODE(dev->multi_mode); |
|---|
| 567 | 713 | writel(val, hw->base_addr + ISP_ACQ_H_OFFS); |
|---|
| 714 | + if (hw->is_unite) |
|---|
| 715 | + writel(val, hw->base_next_addr + ISP_ACQ_H_OFFS); |
|---|
| 716 | + v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, |
|---|
| 717 | + "sensor mode:%d index:%d | 0x%x\n", |
|---|
| 718 | + dev->multi_mode, dev->multi_index, val); |
|---|
| 568 | 719 | } |
|---|
| 569 | 720 | is_upd = true; |
|---|
| 570 | 721 | } |
|---|
| 571 | 722 | |
|---|
| 572 | | - if (dev->isp_ver == ISP_V21) |
|---|
| 723 | + if (dev->isp_ver > ISP_V20) |
|---|
| 573 | 724 | dma2frm = 0; |
|---|
| 574 | 725 | if (dma2frm > 2) |
|---|
| 575 | 726 | dma2frm = 2; |
|---|
| 576 | 727 | if (dma2frm == 2) |
|---|
| 577 | 728 | dev->rdbk_cnt_x3++; |
|---|
| 578 | | - else if (dma2frm == 1) |
|---|
| 729 | + else if (dma2frm == 1 || dev->sw_rd_cnt) |
|---|
| 579 | 730 | dev->rdbk_cnt_x2++; |
|---|
| 580 | 731 | else |
|---|
| 581 | 732 | dev->rdbk_cnt_x1++; |
|---|
| .. | .. |
|---|
| 584 | 735 | rkisp_params_cfgsram(params_vdev); |
|---|
| 585 | 736 | params_vdev->rdbk_times = dma2frm + 1; |
|---|
| 586 | 737 | |
|---|
| 738 | +run_next: |
|---|
| 739 | + if (hw->is_multi_overflow && !dev->is_first_double) { |
|---|
| 740 | + stats_vdev->rdbk_drop = false; |
|---|
| 741 | + if (dev->sw_rd_cnt) { |
|---|
| 742 | + rkisp_multi_overflow_hdl(dev, false); |
|---|
| 743 | + params_vdev->rdbk_times += dev->sw_rd_cnt; |
|---|
| 744 | + stats_vdev->rdbk_drop = true; |
|---|
| 745 | + is_upd = true; |
|---|
| 746 | + } else if (is_try) { |
|---|
| 747 | + rkisp_multi_overflow_hdl(dev, true); |
|---|
| 748 | + is_upd = true; |
|---|
| 749 | + } |
|---|
| 750 | + } |
|---|
| 751 | + |
|---|
| 587 | 752 | /* read 3d lut at frame end */ |
|---|
| 588 | 753 | if (hw->is_single && is_upd && |
|---|
| 589 | 754 | rkisp_read_reg_cache(dev, ISP_3DLUT_UPDATE) & 0x1) { |
|---|
| 590 | | - rkisp_write(dev, ISP_3DLUT_UPDATE, 0, true); |
|---|
| 755 | + rkisp_unite_write(dev, ISP_3DLUT_UPDATE, 0, true, hw->is_unite); |
|---|
| 591 | 756 | is_3dlut_upd = true; |
|---|
| 592 | 757 | } |
|---|
| 593 | 758 | if (is_upd) { |
|---|
| 594 | 759 | val = rkisp_read(dev, ISP_CTRL, false); |
|---|
| 595 | 760 | val |= CIF_ISP_CTRL_ISP_CFG_UPD; |
|---|
| 596 | | - rkisp_write(dev, ISP_CTRL, val, true); |
|---|
| 761 | + rkisp_unite_write(dev, ISP_CTRL, val, true, hw->is_unite); |
|---|
| 762 | + /* bayer pat after ISP_CFG_UPD for multi sensor to read lsc r/g/b table */ |
|---|
| 763 | + rkisp_update_regs(dev, ISP_ACQ_PROP, ISP_ACQ_PROP); |
|---|
| 597 | 764 | /* fix ldch multi sensor case: |
|---|
| 598 | 765 | * ldch will pre-read data when en and isp force upd or frame end, |
|---|
| 599 | 766 | * udelay for ldch pre-read data. |
|---|
| 600 | 767 | * ldch en=0 before start for frame end to stop ldch read data. |
|---|
| 601 | 768 | */ |
|---|
| 602 | | - if (!hw->is_single && |
|---|
| 603 | | - (rkisp_read(dev, ISP_LDCH_BASE, true) & 0x1)) { |
|---|
| 769 | + val = rkisp_read(dev, ISP_LDCH_BASE, true); |
|---|
| 770 | + if (!hw->is_single && val & BIT(0)) { |
|---|
| 604 | 771 | udelay(50); |
|---|
| 605 | | - writel(0, hw->base_addr + ISP_LDCH_BASE); |
|---|
| 772 | + val &= ~(BIT(0) | BIT(31)); |
|---|
| 773 | + writel(val, hw->base_addr + ISP_LDCH_BASE); |
|---|
| 774 | + if (hw->is_unite) |
|---|
| 775 | + writel(val, hw->base_next_addr + ISP_LDCH_BASE); |
|---|
| 606 | 776 | } |
|---|
| 607 | 777 | } |
|---|
| 608 | 778 | if (is_3dlut_upd) |
|---|
| 609 | | - rkisp_write(dev, ISP_3DLUT_UPDATE, 1, true); |
|---|
| 779 | + rkisp_unite_write(dev, ISP_3DLUT_UPDATE, 1, true, hw->is_unite); |
|---|
| 610 | 780 | |
|---|
| 611 | 781 | /* if output stream enable, wait it end */ |
|---|
| 612 | 782 | val = rkisp_read(dev, CIF_MI_CTRL_SHD, true); |
|---|
| .. | .. |
|---|
| 618 | 788 | dev->irq_ends_mask |= ISP_FRAME_SP; |
|---|
| 619 | 789 | else |
|---|
| 620 | 790 | dev->irq_ends_mask &= ~ISP_FRAME_SP; |
|---|
| 621 | | - |
|---|
| 622 | | - memset(dev->filt_state, 0, sizeof(dev->filt_state)); |
|---|
| 623 | | - dev->filt_state[RDBK_F_VS] = dma2frm; |
|---|
| 791 | + if ((dev->isp_ver == ISP_V20 && |
|---|
| 792 | + rkisp_read(dev, ISP_MPFBC_CTRL, true) & SW_MPFBC_EN) || |
|---|
| 793 | + (dev->isp_ver == ISP_V30 && |
|---|
| 794 | + rkisp_read(dev, ISP3X_MPFBC_CTRL, true) & ISP3X_MPFBC_EN_SHD)) |
|---|
| 795 | + dev->irq_ends_mask |= ISP_FRAME_MPFBC; |
|---|
| 796 | + else |
|---|
| 797 | + dev->irq_ends_mask &= ~ISP_FRAME_MPFBC; |
|---|
| 798 | + if ((dev->isp_ver == ISP_V30 && |
|---|
| 799 | + rkisp_read(dev, ISP3X_MI_BP_WR_CTRL, true) & ISP3X_BP_ENABLE) || |
|---|
| 800 | + (dev->isp_ver == ISP_V32 && |
|---|
| 801 | + rkisp_read(dev, ISP32_MI_WR_CTRL2_SHD, true) & ISP32_BP_EN_OUT_SHD)) |
|---|
| 802 | + dev->irq_ends_mask |= ISP_FRAME_BP; |
|---|
| 803 | + else |
|---|
| 804 | + dev->irq_ends_mask &= ~ISP_FRAME_BP; |
|---|
| 624 | 805 | |
|---|
| 625 | 806 | val = rkisp_read(dev, CSI2RX_CTRL0, true); |
|---|
| 626 | 807 | val &= ~SW_IBUF_OP_MODE(0xf); |
|---|
| .. | .. |
|---|
| 629 | 810 | v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, |
|---|
| 630 | 811 | "readback frame:%d time:%d 0x%x\n", |
|---|
| 631 | 812 | cur_frame_id, dma2frm + 1, val); |
|---|
| 632 | | - if (!dma2frm) |
|---|
| 633 | | - rkisp_bridge_update_mi(dev, 0); |
|---|
| 634 | 813 | if (!hw->is_shutdown) |
|---|
| 635 | | - rkisp_write(dev, CSI2RX_CTRL0, val, true); |
|---|
| 814 | + rkisp_unite_write(dev, CSI2RX_CTRL0, val, true, hw->is_unite); |
|---|
| 815 | +} |
|---|
| 816 | + |
|---|
| 817 | +static void rkisp_fast_switch_rx_buf(struct rkisp_device *dev, bool is_current) |
|---|
| 818 | +{ |
|---|
| 819 | + struct rkisp_stream *stream; |
|---|
| 820 | + struct rkisp_buffer *buf; |
|---|
| 821 | + u32 i, val; |
|---|
| 822 | + |
|---|
| 823 | + for (i = RKISP_STREAM_RAWRD0; i < RKISP_MAX_DMARX_STREAM; i++) { |
|---|
| 824 | + stream = &dev->dmarx_dev.stream[i]; |
|---|
| 825 | + if (!stream->ops) |
|---|
| 826 | + continue; |
|---|
| 827 | + buf = NULL; |
|---|
| 828 | + if (is_current) |
|---|
| 829 | + buf = stream->curr_buf; |
|---|
| 830 | + else if (!list_empty(&stream->buf_queue)) |
|---|
| 831 | + buf = list_first_entry(&stream->buf_queue, |
|---|
| 832 | + struct rkisp_buffer, queue); |
|---|
| 833 | + if (!buf) |
|---|
| 834 | + continue; |
|---|
| 835 | + val = buf->buff_addr[RKISP_PLANE_Y]; |
|---|
| 836 | + /* f1 -> f0 -> f1 for normal |
|---|
| 837 | + * L:f1 L:f1 -> L:f0 S:f0 -> L:f1 S:f1 for hdr2 |
|---|
| 838 | + */ |
|---|
| 839 | + if (dev->rd_mode == HDR_RDBK_FRAME2 && !is_current && |
|---|
| 840 | + rkisp_read_reg_cache(dev, ISP3X_HDRMGE_GAIN0) == 0xfff0040) { |
|---|
| 841 | + if (i == RKISP_STREAM_RAWRD2) |
|---|
| 842 | + continue; |
|---|
| 843 | + else |
|---|
| 844 | + rkisp_write(dev, ISP3X_MI_RAWS_RD_BASE, val, false); |
|---|
| 845 | + } |
|---|
| 846 | + rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false); |
|---|
| 847 | + } |
|---|
| 636 | 848 | } |
|---|
| 637 | 849 | |
|---|
| 638 | 850 | static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd) |
|---|
| .. | .. |
|---|
| 644 | 856 | int i, times = -1, max = 0, id = 0; |
|---|
| 645 | 857 | int len[DEV_MAX] = { 0 }; |
|---|
| 646 | 858 | u32 mode = 0; |
|---|
| 859 | + bool is_try = false; |
|---|
| 647 | 860 | |
|---|
| 648 | 861 | spin_lock_irqsave(&hw->rdbk_lock, lock_flags); |
|---|
| 649 | | - if (cmd == T_CMD_END) |
|---|
| 862 | + if (cmd == T_CMD_END) { |
|---|
| 863 | + if (dev->sw_rd_cnt) { |
|---|
| 864 | + dev->sw_rd_cnt--; |
|---|
| 865 | + isp = dev; |
|---|
| 866 | + is_try = true; |
|---|
| 867 | + times = 0; |
|---|
| 868 | + goto end; |
|---|
| 869 | + } |
|---|
| 650 | 870 | hw->is_idle = true; |
|---|
| 871 | + hw->pre_dev_id = dev->dev_id; |
|---|
| 872 | + } |
|---|
| 651 | 873 | if (hw->is_shutdown) |
|---|
| 652 | 874 | hw->is_idle = false; |
|---|
| 653 | 875 | if (!hw->is_idle) |
|---|
| 654 | 876 | goto end; |
|---|
| 655 | 877 | if (hw->monitor.state & ISP_MIPI_ERROR && hw->monitor.is_en) |
|---|
| 656 | 878 | goto end; |
|---|
| 879 | + if (!IS_HDR_RDBK(dev->rd_mode)) |
|---|
| 880 | + goto end; |
|---|
| 657 | 881 | |
|---|
| 658 | 882 | for (i = 0; i < hw->dev_num; i++) { |
|---|
| 659 | 883 | isp = hw->isp[i]; |
|---|
| 660 | | - if (!(isp->isp_state & ISP_START)) |
|---|
| 884 | + if (!isp || |
|---|
| 885 | + (isp && !(isp->isp_state & ISP_START))) |
|---|
| 661 | 886 | continue; |
|---|
| 662 | 887 | rkisp_rdbk_trigger_event(isp, T_CMD_LEN, &len[i]); |
|---|
| 663 | 888 | if (max < len[i]) { |
|---|
| .. | .. |
|---|
| 666 | 891 | } |
|---|
| 667 | 892 | } |
|---|
| 668 | 893 | |
|---|
| 894 | + /* wait 2 frame to start isp for fast */ |
|---|
| 895 | + if (dev->is_pre_on && max == 1 && !atomic_read(&dev->isp_sdev.frm_sync_seq)) |
|---|
| 896 | + goto end; |
|---|
| 897 | + |
|---|
| 669 | 898 | if (max) { |
|---|
| 670 | | - v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, |
|---|
| 671 | | - "trigger fifo len:%d\n", max); |
|---|
| 672 | 899 | isp = hw->isp[id]; |
|---|
| 900 | + v4l2_dbg(2, rkisp_debug, &isp->v4l2_dev, |
|---|
| 901 | + "trigger fifo len:%d\n", max); |
|---|
| 673 | 902 | rkisp_rdbk_trigger_event(isp, T_CMD_DEQUEUE, &t); |
|---|
| 674 | 903 | isp->dmarx_dev.pre_frame = isp->dmarx_dev.cur_frame; |
|---|
| 675 | 904 | if (t.frame_id > isp->dmarx_dev.pre_frame.id && |
|---|
| .. | .. |
|---|
| 680 | 909 | isp->dmarx_dev.cur_frame.sof_timestamp = t.sof_timestamp; |
|---|
| 681 | 910 | isp->dmarx_dev.cur_frame.timestamp = t.frame_timestamp; |
|---|
| 682 | 911 | isp->isp_sdev.frm_timestamp = t.sof_timestamp; |
|---|
| 912 | + atomic_set(&isp->isp_sdev.frm_sync_seq, t.frame_id + 1); |
|---|
| 683 | 913 | mode = t.mode; |
|---|
| 684 | 914 | times = t.times; |
|---|
| 685 | 915 | hw->cur_dev_id = id; |
|---|
| 686 | 916 | hw->is_idle = false; |
|---|
| 917 | + isp->sw_rd_cnt = 0; |
|---|
| 918 | + if (hw->is_multi_overflow && (hw->pre_dev_id != id)) { |
|---|
| 919 | + isp->sw_rd_cnt = 1; |
|---|
| 920 | + times = 0; |
|---|
| 921 | + } |
|---|
| 922 | + if (isp->is_pre_on && t.frame_id == 0) { |
|---|
| 923 | + isp->is_first_double = true; |
|---|
| 924 | + isp->skip_frame = 1; |
|---|
| 925 | + isp->sw_rd_cnt = 0; |
|---|
| 926 | + rkisp_fast_switch_rx_buf(isp, false); |
|---|
| 927 | + } |
|---|
| 687 | 928 | } |
|---|
| 688 | 929 | end: |
|---|
| 689 | 930 | spin_unlock_irqrestore(&hw->rdbk_lock, lock_flags); |
|---|
| 690 | 931 | if (times >= 0) |
|---|
| 691 | | - rkisp_trigger_read_back(isp, times, mode, false); |
|---|
| 932 | + rkisp_trigger_read_back(isp, times, mode, is_try); |
|---|
| 692 | 933 | } |
|---|
| 693 | 934 | |
|---|
| 694 | 935 | int rkisp_rdbk_trigger_event(struct rkisp_device *dev, u32 cmd, void *arg) |
|---|
| .. | .. |
|---|
| 697 | 938 | struct isp2x_csi_trigger *trigger = NULL; |
|---|
| 698 | 939 | unsigned long lock_flags = 0; |
|---|
| 699 | 940 | int val, ret = 0; |
|---|
| 700 | | - |
|---|
| 701 | | - if (dev->dmarx_dev.trigger != T_MANUAL) |
|---|
| 702 | | - return 0; |
|---|
| 703 | 941 | |
|---|
| 704 | 942 | spin_lock_irqsave(&dev->rdbk_lock, lock_flags); |
|---|
| 705 | 943 | switch (cmd) { |
|---|
| .. | .. |
|---|
| 732 | 970 | return ret; |
|---|
| 733 | 971 | } |
|---|
| 734 | 972 | |
|---|
| 973 | +static void rkisp_rdbk_work(struct work_struct *work) |
|---|
| 974 | +{ |
|---|
| 975 | + struct rkisp_device *dev = container_of(work, struct rkisp_device, rdbk_work); |
|---|
| 976 | + |
|---|
| 977 | + rkisp_dvfs(dev); |
|---|
| 978 | + rkisp_rdbk_trigger_event(dev, T_CMD_END, NULL); |
|---|
| 979 | +} |
|---|
| 980 | + |
|---|
| 735 | 981 | void rkisp_check_idle(struct rkisp_device *dev, u32 irq) |
|---|
| 736 | 982 | { |
|---|
| 737 | 983 | u32 val = 0; |
|---|
| 984 | + |
|---|
| 985 | + if (dev->hw_dev->is_multi_overflow && |
|---|
| 986 | + dev->sw_rd_cnt && |
|---|
| 987 | + irq & ISP_FRAME_END && |
|---|
| 988 | + !dev->is_first_double) |
|---|
| 989 | + goto end; |
|---|
| 738 | 990 | |
|---|
| 739 | 991 | dev->irq_ends |= (irq & dev->irq_ends_mask); |
|---|
| 740 | 992 | v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev, |
|---|
| .. | .. |
|---|
| 750 | 1002 | !IS_HDR_RDBK(dev->rd_mode)) |
|---|
| 751 | 1003 | return; |
|---|
| 752 | 1004 | |
|---|
| 1005 | + if (dev->is_first_double) { |
|---|
| 1006 | + rkisp_fast_switch_rx_buf(dev, true); |
|---|
| 1007 | + dev->skip_frame = 0; |
|---|
| 1008 | + dev->irq_ends = 0; |
|---|
| 1009 | + return; |
|---|
| 1010 | + } |
|---|
| 1011 | + |
|---|
| 753 | 1012 | /* check output stream is off */ |
|---|
| 754 | | - val = ISP_FRAME_MP | ISP_FRAME_SP | ISP_FRAME_MPFBC; |
|---|
| 1013 | + val = ISP_FRAME_MP | ISP_FRAME_SP | ISP_FRAME_MPFBC | ISP_FRAME_BP; |
|---|
| 755 | 1014 | if (!(dev->irq_ends_mask & val)) { |
|---|
| 756 | 1015 | u32 state = dev->isp_state; |
|---|
| 757 | 1016 | struct rkisp_stream *s; |
|---|
| 758 | 1017 | |
|---|
| 759 | | - for (val = 0; val <= RKISP_STREAM_SP; val++) { |
|---|
| 1018 | + for (val = 0; val < RKISP_STREAM_VIR; val++) { |
|---|
| 760 | 1019 | s = &dev->cap_dev.stream[val]; |
|---|
| 761 | 1020 | dev->isp_state = ISP_STOP; |
|---|
| 762 | 1021 | if (s->streaming) { |
|---|
| .. | .. |
|---|
| 767 | 1026 | } |
|---|
| 768 | 1027 | |
|---|
| 769 | 1028 | val = 0; |
|---|
| 770 | | - dev->irq_ends = 0; |
|---|
| 771 | 1029 | switch (dev->rd_mode) { |
|---|
| 772 | 1030 | case HDR_RDBK_FRAME3://for rd1 rd0 rd2 |
|---|
| 773 | 1031 | val |= RAW1_RD_FRAME; |
|---|
| .. | .. |
|---|
| 780 | 1038 | /* FALLTHROUGH */ |
|---|
| 781 | 1039 | } |
|---|
| 782 | 1040 | rkisp2_rawrd_isr(val, dev); |
|---|
| 783 | | - if (dev->dmarx_dev.trigger == T_MANUAL) |
|---|
| 1041 | + |
|---|
| 1042 | +end: |
|---|
| 1043 | + dev->irq_ends = 0; |
|---|
| 1044 | + if (dev->hw_dev->is_dvfs) |
|---|
| 1045 | + schedule_work(&dev->rdbk_work); |
|---|
| 1046 | + else |
|---|
| 784 | 1047 | rkisp_rdbk_trigger_event(dev, T_CMD_END, NULL); |
|---|
| 785 | 1048 | if (dev->isp_state == ISP_STOP) |
|---|
| 786 | 1049 | wake_up(&dev->sync_onoff); |
|---|
| .. | .. |
|---|
| 803 | 1066 | */ |
|---|
| 804 | 1067 | static void rkisp_config_ism(struct rkisp_device *dev) |
|---|
| 805 | 1068 | { |
|---|
| 806 | | - void __iomem *base = dev->base_addr; |
|---|
| 807 | 1069 | struct v4l2_rect *out_crop = &dev->isp_sdev.out_crop; |
|---|
| 808 | | - u32 val; |
|---|
| 1070 | + u32 width = out_crop->width, mult = 1; |
|---|
| 1071 | + bool is_unite = dev->hw_dev->is_unite; |
|---|
| 809 | 1072 | |
|---|
| 810 | 1073 | /* isp2.0 no ism */ |
|---|
| 811 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) |
|---|
| 1074 | + if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21 || |
|---|
| 1075 | + dev->isp_ver == ISP_V32_L) |
|---|
| 812 | 1076 | return; |
|---|
| 813 | 1077 | |
|---|
| 814 | | - writel(0, base + CIF_ISP_IS_RECENTER); |
|---|
| 815 | | - writel(0, base + CIF_ISP_IS_MAX_DX); |
|---|
| 816 | | - writel(0, base + CIF_ISP_IS_MAX_DY); |
|---|
| 817 | | - writel(0, base + CIF_ISP_IS_DISPLACE); |
|---|
| 818 | | - writel(out_crop->left, base + CIF_ISP_IS_H_OFFS); |
|---|
| 819 | | - writel(out_crop->top, base + CIF_ISP_IS_V_OFFS); |
|---|
| 820 | | - writel(out_crop->width, base + CIF_ISP_IS_H_SIZE); |
|---|
| 1078 | + if (is_unite) |
|---|
| 1079 | + width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; |
|---|
| 1080 | + rkisp_unite_write(dev, CIF_ISP_IS_RECENTER, 0, false, is_unite); |
|---|
| 1081 | + rkisp_unite_write(dev, CIF_ISP_IS_MAX_DX, 0, false, is_unite); |
|---|
| 1082 | + rkisp_unite_write(dev, CIF_ISP_IS_MAX_DY, 0, false, is_unite); |
|---|
| 1083 | + rkisp_unite_write(dev, CIF_ISP_IS_DISPLACE, 0, false, is_unite); |
|---|
| 1084 | + rkisp_unite_write(dev, CIF_ISP_IS_H_OFFS, out_crop->left, false, is_unite); |
|---|
| 1085 | + rkisp_unite_write(dev, CIF_ISP_IS_V_OFFS, out_crop->top, false, is_unite); |
|---|
| 1086 | + rkisp_unite_write(dev, CIF_ISP_IS_H_SIZE, width, false, is_unite); |
|---|
| 821 | 1087 | if (dev->cap_dev.stream[RKISP_STREAM_SP].interlaced) |
|---|
| 822 | | - writel(out_crop->height / 2, base + CIF_ISP_IS_V_SIZE); |
|---|
| 823 | | - else |
|---|
| 824 | | - writel(out_crop->height, base + CIF_ISP_IS_V_SIZE); |
|---|
| 1088 | + mult = 2; |
|---|
| 1089 | + rkisp_unite_write(dev, CIF_ISP_IS_V_SIZE, out_crop->height / mult, |
|---|
| 1090 | + false, is_unite); |
|---|
| 1091 | + |
|---|
| 1092 | + if (dev->isp_ver == ISP_V30 || dev->isp_ver == ISP_V32) |
|---|
| 1093 | + return; |
|---|
| 825 | 1094 | |
|---|
| 826 | 1095 | /* IS(Image Stabilization) is always on, working as output crop */ |
|---|
| 827 | | - writel(1, base + CIF_ISP_IS_CTRL); |
|---|
| 828 | | - val = readl(base + CIF_ISP_CTRL); |
|---|
| 829 | | - val |= CIF_ISP_CTRL_ISP_CFG_UPD; |
|---|
| 830 | | - writel(val, base + CIF_ISP_CTRL); |
|---|
| 1096 | + rkisp_write(dev, CIF_ISP_IS_CTRL, 1, false); |
|---|
| 831 | 1097 | } |
|---|
| 832 | 1098 | |
|---|
| 833 | 1099 | static int rkisp_reset_handle_v2x(struct rkisp_device *dev) |
|---|
| .. | .. |
|---|
| 984 | 1250 | !(monitor->state & ISP_MIPI_ERROR))) { |
|---|
| 985 | 1251 | for (i = 0; i < hw->dev_num; i++) { |
|---|
| 986 | 1252 | isp = hw->isp[i]; |
|---|
| 987 | | - if (!(isp->isp_inp & INP_CSI)) |
|---|
| 1253 | + if (!isp || (isp && !(isp->isp_inp & INP_CSI))) |
|---|
| 988 | 1254 | continue; |
|---|
| 989 | 1255 | if (!(isp->isp_state & ISP_START)) |
|---|
| 990 | 1256 | break; |
|---|
| .. | .. |
|---|
| 1006 | 1272 | } |
|---|
| 1007 | 1273 | for (i = 0; i < hw->dev_num; i++) { |
|---|
| 1008 | 1274 | isp = hw->isp[i]; |
|---|
| 1275 | + if (!isp) |
|---|
| 1276 | + continue; |
|---|
| 1009 | 1277 | if (isp->isp_inp & INP_CSI || |
|---|
| 1010 | 1278 | isp->isp_inp & INP_DVP || |
|---|
| 1011 | 1279 | isp->isp_inp & INP_LVDS) { |
|---|
| .. | .. |
|---|
| 1032 | 1300 | |
|---|
| 1033 | 1301 | for (i = 0; i < hw->dev_num; i++) { |
|---|
| 1034 | 1302 | isp = hw->isp[i]; |
|---|
| 1303 | + if (!isp) |
|---|
| 1304 | + continue; |
|---|
| 1035 | 1305 | if (isp->isp_inp & INP_CSI || |
|---|
| 1036 | 1306 | isp->isp_inp & INP_DVP || |
|---|
| 1037 | 1307 | isp->isp_inp & INP_LVDS) { |
|---|
| .. | .. |
|---|
| 1085 | 1355 | */ |
|---|
| 1086 | 1356 | static void rkisp_config_color_space(struct rkisp_device *dev) |
|---|
| 1087 | 1357 | { |
|---|
| 1358 | + u32 val = 0; |
|---|
| 1359 | + |
|---|
| 1088 | 1360 | u16 bt601_coeff[] = { |
|---|
| 1089 | 1361 | 0x0026, 0x004b, 0x000f, |
|---|
| 1090 | 1362 | 0x01ea, 0x01d6, 0x0040, |
|---|
| .. | .. |
|---|
| 1116 | 1388 | } |
|---|
| 1117 | 1389 | |
|---|
| 1118 | 1390 | for (i = 0; i < 9; i++) |
|---|
| 1119 | | - rkisp_write(dev, CIF_ISP_CC_COEFF_0 + i * 4, *(coeff + i), false); |
|---|
| 1391 | + rkisp_unite_write(dev, CIF_ISP_CC_COEFF_0 + i * 4, |
|---|
| 1392 | + *(coeff + i), false, dev->hw_dev->is_unite); |
|---|
| 1393 | + |
|---|
| 1394 | + val = rkisp_read_reg_cache(dev, CIF_ISP_CTRL); |
|---|
| 1120 | 1395 | |
|---|
| 1121 | 1396 | if (dev->isp_sdev.quantization == V4L2_QUANTIZATION_FULL_RANGE) |
|---|
| 1122 | | - rkisp_set_bits(dev, CIF_ISP_CTRL, 0, |
|---|
| 1123 | | - CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | |
|---|
| 1124 | | - CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA, false); |
|---|
| 1397 | + rkisp_unite_write(dev, CIF_ISP_CTRL, val | |
|---|
| 1398 | + CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | |
|---|
| 1399 | + CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA, |
|---|
| 1400 | + false, dev->hw_dev->is_unite); |
|---|
| 1125 | 1401 | else |
|---|
| 1126 | | - rkisp_clear_bits(dev, CIF_ISP_CTRL, |
|---|
| 1127 | | - CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | |
|---|
| 1128 | | - CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA, false); |
|---|
| 1402 | + rkisp_unite_write(dev, CIF_ISP_CTRL, val & |
|---|
| 1403 | + ~(CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | |
|---|
| 1404 | + CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA), |
|---|
| 1405 | + false, dev->hw_dev->is_unite); |
|---|
| 1406 | +} |
|---|
| 1407 | + |
|---|
| 1408 | +static void rkisp_config_cmsk_single(struct rkisp_device *dev, |
|---|
| 1409 | + struct rkisp_cmsk_cfg *cfg) |
|---|
| 1410 | +{ |
|---|
| 1411 | + u32 i, val, ctrl = 0; |
|---|
| 1412 | + u32 mp_en = cfg->win[0].win_en; |
|---|
| 1413 | + u32 sp_en = cfg->win[1].win_en; |
|---|
| 1414 | + u32 bp_en = cfg->win[2].win_en; |
|---|
| 1415 | + u32 win_max = (dev->isp_ver == ISP_V30) ? |
|---|
| 1416 | + RKISP_CMSK_WIN_MAX_V30 : RKISP_CMSK_WIN_MAX; |
|---|
| 1417 | + |
|---|
| 1418 | + if (mp_en) { |
|---|
| 1419 | + ctrl |= ISP3X_SW_CMSK_EN_MP; |
|---|
| 1420 | + rkisp_write(dev, ISP3X_CMSK_CTRL1, mp_en, false); |
|---|
| 1421 | + val = cfg->win[0].mode; |
|---|
| 1422 | + rkisp_write(dev, ISP3X_CMSK_CTRL4, val, false); |
|---|
| 1423 | + } |
|---|
| 1424 | + |
|---|
| 1425 | + if (sp_en) { |
|---|
| 1426 | + ctrl |= ISP3X_SW_CMSK_EN_SP; |
|---|
| 1427 | + rkisp_write(dev, ISP3X_CMSK_CTRL2, sp_en, false); |
|---|
| 1428 | + val = cfg->win[1].mode; |
|---|
| 1429 | + rkisp_write(dev, ISP3X_CMSK_CTRL5, val, false); |
|---|
| 1430 | + } |
|---|
| 1431 | + |
|---|
| 1432 | + if (bp_en) { |
|---|
| 1433 | + ctrl |= ISP3X_SW_CMSK_EN_BP; |
|---|
| 1434 | + rkisp_write(dev, ISP3X_CMSK_CTRL3, bp_en, false); |
|---|
| 1435 | + val = cfg->win[2].mode; |
|---|
| 1436 | + rkisp_write(dev, ISP3X_CMSK_CTRL6, val, false); |
|---|
| 1437 | + } |
|---|
| 1438 | + |
|---|
| 1439 | + for (i = 0; i < win_max; i++) { |
|---|
| 1440 | + if (!(mp_en & BIT(i)) && !(sp_en & BIT(i)) && !(bp_en & BIT(i))) |
|---|
| 1441 | + continue; |
|---|
| 1442 | + |
|---|
| 1443 | + val = ISP3X_SW_CMSK_YUV(cfg->win[i].cover_color_y, |
|---|
| 1444 | + cfg->win[i].cover_color_u, |
|---|
| 1445 | + cfg->win[i].cover_color_v); |
|---|
| 1446 | + rkisp_write(dev, ISP3X_CMSK_YUV0 + i * 4, val, false); |
|---|
| 1447 | + |
|---|
| 1448 | + val = ISP_PACK_2SHORT(cfg->win[i].h_offs, cfg->win[i].v_offs); |
|---|
| 1449 | + rkisp_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, false); |
|---|
| 1450 | + |
|---|
| 1451 | + val = ISP_PACK_2SHORT(cfg->win[i].h_size, cfg->win[i].v_size); |
|---|
| 1452 | + rkisp_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, false); |
|---|
| 1453 | + } |
|---|
| 1454 | + |
|---|
| 1455 | + if (ctrl) { |
|---|
| 1456 | + val = ISP_PACK_2SHORT(dev->isp_sdev.out_crop.width, |
|---|
| 1457 | + dev->isp_sdev.out_crop.height); |
|---|
| 1458 | + rkisp_write(dev, ISP3X_CMSK_PIC_SIZE, val, false); |
|---|
| 1459 | + ctrl |= ISP3X_SW_CMSK_EN | ISP3X_SW_CMSK_ORDER_MODE; |
|---|
| 1460 | + ctrl |= ISP3X_SW_CMSK_BLKSIZE(cfg->mosaic_block); |
|---|
| 1461 | + } |
|---|
| 1462 | + rkisp_write(dev, ISP3X_CMSK_CTRL0, ctrl, false); |
|---|
| 1463 | + |
|---|
| 1464 | + val = rkisp_read(dev, ISP3X_CMSK_CTRL0, true); |
|---|
| 1465 | + if (dev->hw_dev->is_single && |
|---|
| 1466 | + ((val & ISP32_SW_CMSK_EN_PATH) != (val & ISP32_SW_CMSK_EN_PATH_SHD))) |
|---|
| 1467 | + rkisp_write(dev, ISP3X_CMSK_CTRL0, val | ISP3X_SW_CMSK_FORCE_UPD, true); |
|---|
| 1468 | +} |
|---|
| 1469 | + |
|---|
| 1470 | +static void rkisp_config_cmsk_dual(struct rkisp_device *dev, |
|---|
| 1471 | + struct rkisp_cmsk_cfg *cfg) |
|---|
| 1472 | +{ |
|---|
| 1473 | + struct rkisp_cmsk_cfg left = *cfg; |
|---|
| 1474 | + struct rkisp_cmsk_cfg right = *cfg; |
|---|
| 1475 | + u32 width = dev->isp_sdev.out_crop.width; |
|---|
| 1476 | + u32 height = dev->isp_sdev.out_crop.height; |
|---|
| 1477 | + u32 w = width / 2; |
|---|
| 1478 | + u32 i, val, h_offs, h_size, ctrl; |
|---|
| 1479 | + u8 mp_en = cfg->win[0].win_en; |
|---|
| 1480 | + u8 sp_en = cfg->win[1].win_en; |
|---|
| 1481 | + u8 bp_en = cfg->win[2].win_en; |
|---|
| 1482 | + u32 win_max = (dev->isp_ver == ISP_V30) ? |
|---|
| 1483 | + RKISP_CMSK_WIN_MAX_V30 : RKISP_CMSK_WIN_MAX; |
|---|
| 1484 | + |
|---|
| 1485 | + for (i = 0; i < win_max; i++) { |
|---|
| 1486 | + if (!(mp_en & BIT(i)) && !(sp_en & BIT(i)) && !(bp_en & BIT(i))) |
|---|
| 1487 | + continue; |
|---|
| 1488 | + |
|---|
| 1489 | + h_offs = cfg->win[i].h_offs; |
|---|
| 1490 | + h_size = cfg->win[i].h_size; |
|---|
| 1491 | + if (h_offs + h_size <= w) { |
|---|
| 1492 | + /* cmsk window at left isp */ |
|---|
| 1493 | + right.win[0].win_en &= ~BIT(i); |
|---|
| 1494 | + right.win[1].win_en &= ~BIT(i); |
|---|
| 1495 | + right.win[2].win_en &= ~BIT(i); |
|---|
| 1496 | + } else if (h_offs >= w) { |
|---|
| 1497 | + /* cmsk window at right isp */ |
|---|
| 1498 | + left.win[0].win_en &= ~BIT(i); |
|---|
| 1499 | + left.win[1].win_en &= ~BIT(i); |
|---|
| 1500 | + left.win[2].win_en &= ~BIT(i); |
|---|
| 1501 | + } else { |
|---|
| 1502 | + /* cmsk window at dual isp */ |
|---|
| 1503 | + left.win[i].h_size = ALIGN(w - h_offs, 8); |
|---|
| 1504 | + |
|---|
| 1505 | + right.win[i].h_offs = RKMOUDLE_UNITE_EXTEND_PIXEL; |
|---|
| 1506 | + val = h_offs + h_size - w; |
|---|
| 1507 | + right.win[i].h_size = ALIGN(val, 8); |
|---|
| 1508 | + right.win[i].h_offs -= right.win[i].h_size - val; |
|---|
| 1509 | + } |
|---|
| 1510 | + |
|---|
| 1511 | + val = ISP3X_SW_CMSK_YUV(left.win[i].cover_color_y, |
|---|
| 1512 | + left.win[i].cover_color_u, |
|---|
| 1513 | + left.win[i].cover_color_v); |
|---|
| 1514 | + rkisp_write(dev, ISP3X_CMSK_YUV0 + i * 4, val, false); |
|---|
| 1515 | + rkisp_next_write(dev, ISP3X_CMSK_YUV0 + i * 4, val, false); |
|---|
| 1516 | + |
|---|
| 1517 | + val = ISP_PACK_2SHORT(left.win[i].h_offs, left.win[i].v_offs); |
|---|
| 1518 | + rkisp_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, false); |
|---|
| 1519 | + val = ISP_PACK_2SHORT(left.win[i].h_size, left.win[i].v_size); |
|---|
| 1520 | + rkisp_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, false); |
|---|
| 1521 | + |
|---|
| 1522 | + val = ISP_PACK_2SHORT(right.win[i].h_offs, right.win[i].v_offs); |
|---|
| 1523 | + rkisp_next_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, false); |
|---|
| 1524 | + val = ISP_PACK_2SHORT(right.win[i].h_size, right.win[i].v_size); |
|---|
| 1525 | + rkisp_next_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, false); |
|---|
| 1526 | + } |
|---|
| 1527 | + |
|---|
| 1528 | + w += RKMOUDLE_UNITE_EXTEND_PIXEL; |
|---|
| 1529 | + ctrl = 0; |
|---|
| 1530 | + if (left.win[0].win_en) { |
|---|
| 1531 | + ctrl |= ISP3X_SW_CMSK_EN_MP; |
|---|
| 1532 | + rkisp_write(dev, ISP3X_CMSK_CTRL1, left.win[0].win_en, false); |
|---|
| 1533 | + val = left.win[0].mode; |
|---|
| 1534 | + rkisp_write(dev, ISP3X_CMSK_CTRL4, val, false); |
|---|
| 1535 | + } |
|---|
| 1536 | + if (left.win[1].win_en) { |
|---|
| 1537 | + ctrl |= ISP3X_SW_CMSK_EN_SP; |
|---|
| 1538 | + rkisp_write(dev, ISP3X_CMSK_CTRL2, left.win[1].win_en, false); |
|---|
| 1539 | + val = left.win[1].mode; |
|---|
| 1540 | + rkisp_write(dev, ISP3X_CMSK_CTRL5, val, false); |
|---|
| 1541 | + } |
|---|
| 1542 | + if (left.win[2].win_en) { |
|---|
| 1543 | + ctrl |= ISP3X_SW_CMSK_EN_BP; |
|---|
| 1544 | + rkisp_write(dev, ISP3X_CMSK_CTRL3, left.win[2].win_en, false); |
|---|
| 1545 | + val = left.win[2].mode; |
|---|
| 1546 | + rkisp_write(dev, ISP3X_CMSK_CTRL6, val, false); |
|---|
| 1547 | + } |
|---|
| 1548 | + if (ctrl) { |
|---|
| 1549 | + val = ISP_PACK_2SHORT(w, height); |
|---|
| 1550 | + rkisp_write(dev, ISP3X_CMSK_PIC_SIZE, val, false); |
|---|
| 1551 | + ctrl |= ISP3X_SW_CMSK_EN | ISP3X_SW_CMSK_ORDER_MODE; |
|---|
| 1552 | + } |
|---|
| 1553 | + rkisp_write(dev, ISP3X_CMSK_CTRL0, ctrl, false); |
|---|
| 1554 | + |
|---|
| 1555 | + ctrl = 0; |
|---|
| 1556 | + if (right.win[0].win_en) { |
|---|
| 1557 | + ctrl |= ISP3X_SW_CMSK_EN_MP; |
|---|
| 1558 | + rkisp_next_write(dev, ISP3X_CMSK_CTRL1, right.win[0].win_en, false); |
|---|
| 1559 | + val = right.win[0].mode; |
|---|
| 1560 | + rkisp_next_write(dev, ISP3X_CMSK_CTRL4, val, false); |
|---|
| 1561 | + } |
|---|
| 1562 | + if (right.win[1].win_en) { |
|---|
| 1563 | + ctrl |= ISP3X_SW_CMSK_EN_SP; |
|---|
| 1564 | + rkisp_next_write(dev, ISP3X_CMSK_CTRL2, right.win[1].win_en, false); |
|---|
| 1565 | + val = right.win[1].mode; |
|---|
| 1566 | + rkisp_next_write(dev, ISP3X_CMSK_CTRL5, val, false); |
|---|
| 1567 | + } |
|---|
| 1568 | + if (right.win[2].win_en) { |
|---|
| 1569 | + ctrl |= ISP3X_SW_CMSK_EN_BP; |
|---|
| 1570 | + rkisp_next_write(dev, ISP3X_CMSK_CTRL3, right.win[2].win_en, false); |
|---|
| 1571 | + val = right.win[2].mode; |
|---|
| 1572 | + rkisp_next_write(dev, ISP3X_CMSK_CTRL6, val, false); |
|---|
| 1573 | + } |
|---|
| 1574 | + if (ctrl) { |
|---|
| 1575 | + val = ISP_PACK_2SHORT(w, height); |
|---|
| 1576 | + rkisp_next_write(dev, ISP3X_CMSK_PIC_SIZE, val, false); |
|---|
| 1577 | + ctrl |= ISP3X_SW_CMSK_EN | ISP3X_SW_CMSK_ORDER_MODE; |
|---|
| 1578 | + } |
|---|
| 1579 | + rkisp_next_write(dev, ISP3X_CMSK_CTRL0, ctrl, false); |
|---|
| 1580 | + |
|---|
| 1581 | + val = rkisp_next_read(dev, ISP3X_CMSK_CTRL0, true); |
|---|
| 1582 | + if (dev->hw_dev->is_single && |
|---|
| 1583 | + ((val & ISP32_SW_CMSK_EN_PATH) != (val & ISP32_SW_CMSK_EN_PATH_SHD))) |
|---|
| 1584 | + rkisp_next_write(dev, ISP3X_CMSK_CTRL0, val | ISP3X_SW_CMSK_FORCE_UPD, false); |
|---|
| 1585 | +} |
|---|
| 1586 | + |
|---|
| 1587 | +static void rkisp_config_cmsk(struct rkisp_device *dev) |
|---|
| 1588 | +{ |
|---|
| 1589 | + unsigned long lock_flags = 0; |
|---|
| 1590 | + struct rkisp_cmsk_cfg cfg; |
|---|
| 1591 | + |
|---|
| 1592 | + if (dev->isp_ver != ISP_V30 && dev->isp_ver != ISP_V32) |
|---|
| 1593 | + return; |
|---|
| 1594 | + |
|---|
| 1595 | + spin_lock_irqsave(&dev->cmsk_lock, lock_flags); |
|---|
| 1596 | + if (!dev->is_cmsk_upd) { |
|---|
| 1597 | + spin_unlock_irqrestore(&dev->cmsk_lock, lock_flags); |
|---|
| 1598 | + return; |
|---|
| 1599 | + } |
|---|
| 1600 | + dev->is_cmsk_upd = false; |
|---|
| 1601 | + cfg = dev->cmsk_cfg; |
|---|
| 1602 | + spin_unlock_irqrestore(&dev->cmsk_lock, lock_flags); |
|---|
| 1603 | + |
|---|
| 1604 | + if (!dev->hw_dev->is_unite) |
|---|
| 1605 | + rkisp_config_cmsk_single(dev, &cfg); |
|---|
| 1606 | + else |
|---|
| 1607 | + rkisp_config_cmsk_dual(dev, &cfg); |
|---|
| 1129 | 1608 | } |
|---|
| 1130 | 1609 | |
|---|
| 1131 | 1610 | /* |
|---|
| .. | .. |
|---|
| 1137 | 1616 | struct ispsd_out_fmt *out_fmt; |
|---|
| 1138 | 1617 | struct v4l2_rect *in_crop; |
|---|
| 1139 | 1618 | struct rkisp_sensor_info *sensor; |
|---|
| 1619 | + bool is_unite = dev->hw_dev->is_unite; |
|---|
| 1140 | 1620 | u32 isp_ctrl = 0; |
|---|
| 1141 | 1621 | u32 irq_mask = 0; |
|---|
| 1142 | 1622 | u32 signal = 0; |
|---|
| 1143 | 1623 | u32 acq_mult = 0; |
|---|
| 1144 | 1624 | u32 acq_prop = 0; |
|---|
| 1145 | 1625 | u32 extend_line = 0; |
|---|
| 1626 | + u32 width; |
|---|
| 1146 | 1627 | |
|---|
| 1147 | 1628 | sensor = dev->active_sensor; |
|---|
| 1148 | 1629 | in_fmt = &dev->isp_sdev.in_fmt; |
|---|
| 1149 | 1630 | out_fmt = &dev->isp_sdev.out_fmt; |
|---|
| 1150 | 1631 | in_crop = &dev->isp_sdev.in_crop; |
|---|
| 1632 | + width = in_crop->width; |
|---|
| 1151 | 1633 | |
|---|
| 1152 | 1634 | if (in_fmt->fmt_type == FMT_BAYER) { |
|---|
| 1153 | 1635 | acq_mult = 1; |
|---|
| .. | .. |
|---|
| 1163 | 1645 | if (in_fmt->mbus_code == MEDIA_BUS_FMT_Y8_1X8 || |
|---|
| 1164 | 1646 | in_fmt->mbus_code == MEDIA_BUS_FMT_Y10_1X10 || |
|---|
| 1165 | 1647 | in_fmt->mbus_code == MEDIA_BUS_FMT_Y12_1X12) { |
|---|
| 1166 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) |
|---|
| 1167 | | - rkisp_write(dev, ISP_DEBAYER_CONTROL, 0, false); |
|---|
| 1648 | + if (dev->isp_ver >= ISP_V20) |
|---|
| 1649 | + rkisp_unite_write(dev, ISP_DEBAYER_CONTROL, |
|---|
| 1650 | + 0, false, is_unite); |
|---|
| 1168 | 1651 | else |
|---|
| 1169 | 1652 | rkisp_write(dev, CIF_ISP_DEMOSAIC, |
|---|
| 1170 | 1653 | CIF_ISP_DEMOSAIC_BYPASS | |
|---|
| 1171 | 1654 | CIF_ISP_DEMOSAIC_TH(0xc), false); |
|---|
| 1172 | 1655 | } else { |
|---|
| 1173 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) |
|---|
| 1174 | | - rkisp_write(dev, ISP_DEBAYER_CONTROL, |
|---|
| 1175 | | - SW_DEBAYER_EN | |
|---|
| 1176 | | - SW_DEBAYER_FILTER_G_EN | |
|---|
| 1177 | | - SW_DEBAYER_FILTER_C_EN, false); |
|---|
| 1656 | + if (dev->isp_ver >= ISP_V20) |
|---|
| 1657 | + rkisp_unite_write(dev, ISP_DEBAYER_CONTROL, |
|---|
| 1658 | + SW_DEBAYER_EN | |
|---|
| 1659 | + SW_DEBAYER_FILTER_G_EN | |
|---|
| 1660 | + SW_DEBAYER_FILTER_C_EN, |
|---|
| 1661 | + false, is_unite); |
|---|
| 1178 | 1662 | else |
|---|
| 1179 | 1663 | rkisp_write(dev, CIF_ISP_DEMOSAIC, |
|---|
| 1180 | 1664 | CIF_ISP_DEMOSAIC_TH(0xc), false); |
|---|
| .. | .. |
|---|
| 1195 | 1679 | } else if (in_fmt->fmt_type == FMT_YUV) { |
|---|
| 1196 | 1680 | acq_mult = 2; |
|---|
| 1197 | 1681 | if (sensor && |
|---|
| 1198 | | - (sensor->mbus.type == V4L2_MBUS_CSI2 || |
|---|
| 1682 | + (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY || |
|---|
| 1199 | 1683 | sensor->mbus.type == V4L2_MBUS_CCP2)) { |
|---|
| 1200 | 1684 | isp_ctrl = CIF_ISP_CTRL_ISP_MODE_ITU601; |
|---|
| 1201 | 1685 | } else { |
|---|
| .. | .. |
|---|
| 1227 | 1711 | signal |= CIF_ISP_ACQ_PROP_HSYNC_LOW; |
|---|
| 1228 | 1712 | } |
|---|
| 1229 | 1713 | |
|---|
| 1230 | | - rkisp_write(dev, CIF_ISP_CTRL, isp_ctrl, false); |
|---|
| 1714 | + if (rkisp_read_reg_cache(dev, CIF_ISP_CTRL) & ISP32_MIR_ENABLE) |
|---|
| 1715 | + isp_ctrl |= ISP32_MIR_ENABLE; |
|---|
| 1716 | + |
|---|
| 1717 | + rkisp_unite_write(dev, CIF_ISP_CTRL, isp_ctrl, false, is_unite); |
|---|
| 1231 | 1718 | acq_prop |= signal | in_fmt->yuv_seq | |
|---|
| 1232 | 1719 | CIF_ISP_ACQ_PROP_BAYER_PAT(in_fmt->bayer_pat) | |
|---|
| 1233 | 1720 | CIF_ISP_ACQ_PROP_FIELD_SEL_ALL; |
|---|
| 1234 | | - rkisp_write(dev, CIF_ISP_ACQ_PROP, acq_prop, false); |
|---|
| 1235 | | - rkisp_write(dev, CIF_ISP_ACQ_NR_FRAMES, 0, true); |
|---|
| 1721 | + rkisp_unite_write(dev, CIF_ISP_ACQ_PROP, acq_prop, false, is_unite); |
|---|
| 1722 | + rkisp_unite_write(dev, CIF_ISP_ACQ_NR_FRAMES, 0, true, is_unite); |
|---|
| 1236 | 1723 | |
|---|
| 1724 | + if (is_unite) |
|---|
| 1725 | + width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; |
|---|
| 1237 | 1726 | /* Acquisition Size */ |
|---|
| 1238 | | - rkisp_write(dev, CIF_ISP_ACQ_H_OFFS, acq_mult * in_crop->left, false); |
|---|
| 1239 | | - rkisp_write(dev, CIF_ISP_ACQ_V_OFFS, in_crop->top, false); |
|---|
| 1240 | | - rkisp_write(dev, CIF_ISP_ACQ_H_SIZE, acq_mult * in_crop->width, false); |
|---|
| 1727 | + rkisp_unite_write(dev, CIF_ISP_ACQ_H_OFFS, acq_mult * in_crop->left, |
|---|
| 1728 | + false, is_unite); |
|---|
| 1729 | + rkisp_unite_write(dev, CIF_ISP_ACQ_V_OFFS, in_crop->top, |
|---|
| 1730 | + false, is_unite); |
|---|
| 1731 | + rkisp_unite_write(dev, CIF_ISP_ACQ_H_SIZE, acq_mult * width, |
|---|
| 1732 | + false, is_unite); |
|---|
| 1241 | 1733 | |
|---|
| 1242 | 1734 | /* ISP Out Area differ with ACQ is only FIFO, so don't crop in this */ |
|---|
| 1243 | | - rkisp_write(dev, CIF_ISP_OUT_H_OFFS, 0, true); |
|---|
| 1244 | | - rkisp_write(dev, CIF_ISP_OUT_V_OFFS, 0, true); |
|---|
| 1245 | | - rkisp_write(dev, CIF_ISP_OUT_H_SIZE, in_crop->width, false); |
|---|
| 1735 | + rkisp_unite_write(dev, CIF_ISP_OUT_H_OFFS, 0, true, is_unite); |
|---|
| 1736 | + rkisp_unite_write(dev, CIF_ISP_OUT_V_OFFS, 0, true, is_unite); |
|---|
| 1737 | + rkisp_unite_write(dev, CIF_ISP_OUT_H_SIZE, width, false, is_unite); |
|---|
| 1246 | 1738 | |
|---|
| 1247 | 1739 | if (dev->cap_dev.stream[RKISP_STREAM_SP].interlaced) { |
|---|
| 1248 | | - rkisp_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height / 2, false); |
|---|
| 1249 | | - rkisp_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height / 2, false); |
|---|
| 1740 | + rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height / 2, |
|---|
| 1741 | + false, is_unite); |
|---|
| 1742 | + rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height / 2, |
|---|
| 1743 | + false, is_unite); |
|---|
| 1250 | 1744 | } else { |
|---|
| 1251 | | - rkisp_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height + extend_line, false); |
|---|
| 1252 | | - rkisp_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height + extend_line, false); |
|---|
| 1745 | + rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height + extend_line, |
|---|
| 1746 | + false, is_unite); |
|---|
| 1747 | + rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height + extend_line, |
|---|
| 1748 | + false, is_unite); |
|---|
| 1253 | 1749 | } |
|---|
| 1254 | 1750 | |
|---|
| 1255 | 1751 | /* interrupt mask */ |
|---|
| 1256 | | - irq_mask |= CIF_ISP_FRAME | CIF_ISP_V_START | CIF_ISP_PIC_SIZE_ERROR | |
|---|
| 1257 | | - CIF_ISP_FRAME_IN; |
|---|
| 1258 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) |
|---|
| 1752 | + irq_mask |= CIF_ISP_FRAME | CIF_ISP_V_START | CIF_ISP_PIC_SIZE_ERROR; |
|---|
| 1753 | + if (dev->isp_ver >= ISP_V20) |
|---|
| 1259 | 1754 | irq_mask |= ISP2X_LSC_LUT_ERR; |
|---|
| 1260 | | - rkisp_write(dev, CIF_ISP_IMSC, irq_mask, true); |
|---|
| 1755 | + if (dev->is_pre_on) |
|---|
| 1756 | + irq_mask |= CIF_ISP_FRAME_IN; |
|---|
| 1757 | + rkisp_unite_write(dev, CIF_ISP_IMSC, irq_mask, true, is_unite); |
|---|
| 1261 | 1758 | |
|---|
| 1262 | | - if ((dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) && |
|---|
| 1759 | + if ((dev->isp_ver == ISP_V20 || |
|---|
| 1760 | + dev->isp_ver == ISP_V21) && |
|---|
| 1263 | 1761 | IS_HDR_RDBK(dev->hdr.op_mode)) { |
|---|
| 1264 | 1762 | irq_mask = ISP2X_3A_RAWAE_BIG; |
|---|
| 1265 | 1763 | rkisp_write(dev, ISP_ISP3A_IMSC, irq_mask, true); |
|---|
| .. | .. |
|---|
| 1276 | 1774 | rkisp_update_regs(dev, CIF_ISP_ACQ_H_OFFS, CIF_ISP_ACQ_V_SIZE); |
|---|
| 1277 | 1775 | rkisp_update_regs(dev, CIF_ISP_OUT_H_SIZE, CIF_ISP_OUT_V_SIZE); |
|---|
| 1278 | 1776 | } |
|---|
| 1777 | + |
|---|
| 1778 | + rkisp_config_cmsk(dev); |
|---|
| 1279 | 1779 | return 0; |
|---|
| 1280 | 1780 | } |
|---|
| 1281 | 1781 | |
|---|
| .. | .. |
|---|
| 1379 | 1879 | /* Configure MUX */ |
|---|
| 1380 | 1880 | static int rkisp_config_path(struct rkisp_device *dev) |
|---|
| 1381 | 1881 | { |
|---|
| 1382 | | - int ret = 0; |
|---|
| 1383 | 1882 | struct rkisp_sensor_info *sensor = dev->active_sensor; |
|---|
| 1384 | | - u32 dpcl = readl(dev->base_addr + CIF_VI_DPCL); |
|---|
| 1883 | + int ret = 0; |
|---|
| 1884 | + u32 dpcl = 0; |
|---|
| 1385 | 1885 | |
|---|
| 1386 | 1886 | /* isp input interface selects */ |
|---|
| 1387 | | - if ((sensor && sensor->mbus.type == V4L2_MBUS_CSI2) || |
|---|
| 1887 | + if ((sensor && sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) || |
|---|
| 1388 | 1888 | dev->isp_inp & (INP_RAWRD0 | INP_RAWRD1 | INP_RAWRD2 | INP_CIF)) { |
|---|
| 1389 | 1889 | /* mipi sensor->isp or isp read from ddr */ |
|---|
| 1390 | 1890 | dpcl |= CIF_VI_DPCL_IF_SEL_MIPI; |
|---|
| .. | .. |
|---|
| 1406 | 1906 | ret = -EINVAL; |
|---|
| 1407 | 1907 | } |
|---|
| 1408 | 1908 | |
|---|
| 1409 | | - /* fix 3a_wr no output with selfpath */ |
|---|
| 1410 | | - if (dev->isp_ver == ISP_V21) |
|---|
| 1411 | | - dpcl |= CIF_VI_DPCL_CHAN_MODE_MP | CIF_VI_DPCL_MP_MUX_MRSZ_MI; |
|---|
| 1909 | + if (dev->isp_ver == ISP_V32) |
|---|
| 1910 | + dpcl |= BIT(0); |
|---|
| 1412 | 1911 | |
|---|
| 1413 | | - writel(dpcl, dev->base_addr + CIF_VI_DPCL); |
|---|
| 1414 | | - |
|---|
| 1912 | + rkisp_unite_set_bits(dev, CIF_VI_DPCL, 0, dpcl, true, |
|---|
| 1913 | + dev->hw_dev->is_unite); |
|---|
| 1415 | 1914 | return ret; |
|---|
| 1416 | 1915 | } |
|---|
| 1417 | 1916 | |
|---|
| .. | .. |
|---|
| 1483 | 1982 | int ret = 1000; |
|---|
| 1484 | 1983 | |
|---|
| 1485 | 1984 | if (!rkisp_is_need_3a(dev) || dev->isp_ver == ISP_V20 || |
|---|
| 1486 | | - !params_vdev->is_subs_evt) |
|---|
| 1985 | + !params_vdev->is_subs_evt || dev->hw_dev->is_shutdown) |
|---|
| 1487 | 1986 | return; |
|---|
| 1488 | 1987 | |
|---|
| 1489 | 1988 | v4l2_event_queue(vdev, &ev); |
|---|
| .. | .. |
|---|
| 1500 | 1999 | /* Mess register operations to stop isp */ |
|---|
| 1501 | 2000 | static int rkisp_isp_stop(struct rkisp_device *dev) |
|---|
| 1502 | 2001 | { |
|---|
| 2002 | + struct rkisp_hw_dev *hw = dev->hw_dev; |
|---|
| 1503 | 2003 | void __iomem *base = dev->base_addr; |
|---|
| 1504 | 2004 | unsigned long old_rate, safe_rate; |
|---|
| 1505 | 2005 | u32 val; |
|---|
| .. | .. |
|---|
| 1523 | 2023 | readl(base + CIF_ISP_CSI0_ERR1); |
|---|
| 1524 | 2024 | readl(base + CIF_ISP_CSI0_ERR2); |
|---|
| 1525 | 2025 | readl(base + CIF_ISP_CSI0_ERR3); |
|---|
| 1526 | | - } else if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) { |
|---|
| 2026 | + } else if (dev->isp_ver >= ISP_V20) { |
|---|
| 1527 | 2027 | writel(0, base + CSI2RX_MASK_PHY); |
|---|
| 1528 | 2028 | writel(0, base + CSI2RX_MASK_PACKET); |
|---|
| 1529 | 2029 | writel(0, base + CSI2RX_MASK_OVERFLOW); |
|---|
| .. | .. |
|---|
| 1540 | 2040 | writel(0, base + CIF_ISP_IMSC); |
|---|
| 1541 | 2041 | writel(~0, base + CIF_ISP_ICR); |
|---|
| 1542 | 2042 | |
|---|
| 1543 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) { |
|---|
| 2043 | + if (dev->isp_ver >= ISP_V20) { |
|---|
| 1544 | 2044 | writel(0, base + ISP_ISP3A_IMSC); |
|---|
| 1545 | 2045 | writel(~0, base + ISP_ISP3A_ICR); |
|---|
| 1546 | 2046 | } |
|---|
| .. | .. |
|---|
| 1556 | 2056 | udelay(20); |
|---|
| 1557 | 2057 | } |
|---|
| 1558 | 2058 | /* stop lsc to avoid lsclut error */ |
|---|
| 1559 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) |
|---|
| 2059 | + if (dev->isp_ver >= ISP_V20) |
|---|
| 1560 | 2060 | writel(0, base + ISP_LSC_CTRL); |
|---|
| 1561 | 2061 | /* stop ISP */ |
|---|
| 1562 | 2062 | val = readl(base + CIF_ISP_CTRL); |
|---|
| .. | .. |
|---|
| 1565 | 2065 | |
|---|
| 1566 | 2066 | val = readl(base + CIF_ISP_CTRL); |
|---|
| 1567 | 2067 | writel(val | CIF_ISP_CTRL_ISP_CFG_UPD, base + CIF_ISP_CTRL); |
|---|
| 2068 | + if (hw->is_unite) |
|---|
| 2069 | + rkisp_next_write(dev, CIF_ISP_CTRL, |
|---|
| 2070 | + val | CIF_ISP_CTRL_ISP_CFG_UPD, true); |
|---|
| 1568 | 2071 | |
|---|
| 1569 | 2072 | readx_poll_timeout_atomic(readl, base + CIF_ISP_RIS, |
|---|
| 1570 | 2073 | val, val & CIF_ISP_OFF, 20, 100); |
|---|
| .. | .. |
|---|
| 1572 | 2075 | "MI_CTRL:%x, ISP_CTRL:%x\n", |
|---|
| 1573 | 2076 | readl(base + CIF_MI_CTRL), readl(base + CIF_ISP_CTRL)); |
|---|
| 1574 | 2077 | |
|---|
| 1575 | | - val = rkisp_read(dev, CTRL_VI_ISP_CLK_CTRL, true); |
|---|
| 1576 | 2078 | if (!in_interrupt()) { |
|---|
| 1577 | 2079 | /* normal case */ |
|---|
| 1578 | 2080 | /* check the isp_clk before isp reset operation */ |
|---|
| 1579 | | - old_rate = clk_get_rate(dev->hw_dev->clks[0]); |
|---|
| 1580 | | - safe_rate = dev->hw_dev->clk_rate_tbl[0].clk_rate * 1000000UL; |
|---|
| 2081 | + old_rate = clk_get_rate(hw->clks[0]); |
|---|
| 2082 | + safe_rate = hw->clk_rate_tbl[0].clk_rate * 1000000UL; |
|---|
| 1581 | 2083 | if (old_rate > safe_rate) { |
|---|
| 1582 | | - rkisp_set_clk_rate(dev->hw_dev->clks[0], safe_rate); |
|---|
| 2084 | + rkisp_set_clk_rate(hw->clks[0], safe_rate); |
|---|
| 2085 | + if (hw->is_unite) |
|---|
| 2086 | + rkisp_set_clk_rate(hw->clks[5], safe_rate); |
|---|
| 1583 | 2087 | udelay(100); |
|---|
| 1584 | 2088 | } |
|---|
| 1585 | 2089 | rkisp_soft_reset(dev->hw_dev, false); |
|---|
| 1586 | 2090 | } |
|---|
| 1587 | | - rkisp_write(dev, CTRL_VI_ISP_CLK_CTRL, val, true); |
|---|
| 1588 | 2091 | |
|---|
| 1589 | 2092 | if (dev->isp_ver == ISP_V12 || dev->isp_ver == ISP_V13) { |
|---|
| 1590 | 2093 | writel(0, base + CIF_ISP_CSI0_CSI2_RESETN); |
|---|
| .. | .. |
|---|
| 1592 | 2095 | writel(0, base + CIF_ISP_CSI0_MASK1); |
|---|
| 1593 | 2096 | writel(0, base + CIF_ISP_CSI0_MASK2); |
|---|
| 1594 | 2097 | writel(0, base + CIF_ISP_CSI0_MASK3); |
|---|
| 1595 | | - } else if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) { |
|---|
| 2098 | + } else if (dev->isp_ver >= ISP_V20) { |
|---|
| 1596 | 2099 | writel(0, base + CSI2RX_CSI2_RESETN); |
|---|
| 2100 | + if (hw->is_unite) |
|---|
| 2101 | + rkisp_next_write(dev, CSI2RX_CSI2_RESETN, 0, true); |
|---|
| 1597 | 2102 | } |
|---|
| 1598 | 2103 | |
|---|
| 2104 | + hw->is_dvfs = false; |
|---|
| 2105 | + hw->is_runing = false; |
|---|
| 1599 | 2106 | dev->hw_dev->is_idle = true; |
|---|
| 1600 | 2107 | dev->hw_dev->is_mi_update = false; |
|---|
| 1601 | 2108 | end: |
|---|
| 1602 | 2109 | dev->irq_ends_mask = 0; |
|---|
| 1603 | 2110 | dev->hdr.op_mode = 0; |
|---|
| 2111 | + dev->sw_rd_cnt = 0; |
|---|
| 1604 | 2112 | rkisp_set_state(&dev->isp_state, ISP_STOP); |
|---|
| 1605 | 2113 | |
|---|
| 1606 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) |
|---|
| 2114 | + if (dev->isp_ver >= ISP_V20) |
|---|
| 1607 | 2115 | kfifo_reset(&dev->rdbk_kfifo); |
|---|
| 2116 | + if (dev->isp_ver == ISP_V30 || dev->isp_ver == ISP_V32) |
|---|
| 2117 | + memset(&dev->cmsk_cfg, 0, sizeof(dev->cmsk_cfg)); |
|---|
| 1608 | 2118 | if (dev->emd_vc <= CIF_ISP_ADD_DATA_VC_MAX) { |
|---|
| 1609 | 2119 | for (i = 0; i < RKISP_EMDDATA_FIFO_MAX; i++) |
|---|
| 1610 | 2120 | kfifo_free(&dev->emd_data_fifo[i].mipi_kfifo); |
|---|
| .. | .. |
|---|
| 1622 | 2132 | { |
|---|
| 1623 | 2133 | struct rkisp_sensor_info *sensor = dev->active_sensor; |
|---|
| 1624 | 2134 | void __iomem *base = dev->base_addr; |
|---|
| 1625 | | - u32 val; |
|---|
| 1626 | 2135 | bool is_direct = true; |
|---|
| 2136 | + u32 val; |
|---|
| 1627 | 2137 | |
|---|
| 1628 | 2138 | v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, |
|---|
| 1629 | | - "%s refcnt:%d\n", __func__, |
|---|
| 1630 | | - atomic_read(&dev->hw_dev->refcnt)); |
|---|
| 2139 | + "%s refcnt:%d link_num:%d\n", __func__, |
|---|
| 2140 | + atomic_read(&dev->hw_dev->refcnt), |
|---|
| 2141 | + dev->hw_dev->dev_link_num); |
|---|
| 2142 | + |
|---|
| 2143 | + dev->cap_dev.is_done_early = false; |
|---|
| 2144 | + if (dev->cap_dev.wait_line >= dev->isp_sdev.out_crop.height) |
|---|
| 2145 | + dev->cap_dev.wait_line = 0; |
|---|
| 2146 | + if (dev->cap_dev.wait_line) { |
|---|
| 2147 | + dev->cap_dev.is_done_early = true; |
|---|
| 2148 | + if (dev->isp_ver >= ISP_V32) { |
|---|
| 2149 | + val = dev->cap_dev.wait_line; |
|---|
| 2150 | + rkisp_write(dev, ISP32_ISP_IRQ_CFG0, val << 16, false); |
|---|
| 2151 | + rkisp_set_bits(dev, CIF_ISP_IMSC, 0, ISP3X_OUT_FRM_HALF, false); |
|---|
| 2152 | + } else { |
|---|
| 2153 | + /* using AF 15x15 block */ |
|---|
| 2154 | + val = dev->isp_sdev.out_crop.height / 15; |
|---|
| 2155 | + val = dev->cap_dev.wait_line / val; |
|---|
| 2156 | + val = ISP3X_RAWAF_INELINE0(val) | ISP3X_RAWAF_INTLINE0_EN; |
|---|
| 2157 | + rkisp_unite_write(dev, ISP3X_RAWAF_INT_LINE, |
|---|
| 2158 | + val, false, dev->hw_dev->is_unite); |
|---|
| 2159 | + rkisp_unite_set_bits(dev, ISP_ISP3A_IMSC, 0, |
|---|
| 2160 | + ISP2X_3A_RAWAF, false, dev->hw_dev->is_unite); |
|---|
| 2161 | + rkisp_unite_clear_bits(dev, CIF_ISP_IMSC, |
|---|
| 2162 | + ISP2X_LSC_LUT_ERR, false, dev->hw_dev->is_unite); |
|---|
| 2163 | + dev->rawaf_irq_cnt = 0; |
|---|
| 2164 | + } |
|---|
| 2165 | + } |
|---|
| 1631 | 2166 | |
|---|
| 1632 | 2167 | /* Activate MIPI */ |
|---|
| 1633 | | - if (sensor && sensor->mbus.type == V4L2_MBUS_CSI2) { |
|---|
| 2168 | + if (sensor && sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) { |
|---|
| 1634 | 2169 | if (dev->isp_ver == ISP_V12 || dev->isp_ver == ISP_V13) { |
|---|
| 1635 | 2170 | /* clear interrupts state */ |
|---|
| 1636 | 2171 | readl(base + CIF_ISP_CSI0_ERR1); |
|---|
| .. | .. |
|---|
| 1645 | 2180 | } |
|---|
| 1646 | 2181 | } |
|---|
| 1647 | 2182 | /* Activate ISP */ |
|---|
| 1648 | | - val = rkisp_read(dev, CIF_ISP_CTRL, false); |
|---|
| 2183 | + val = rkisp_read_reg_cache(dev, CIF_ISP_CTRL); |
|---|
| 1649 | 2184 | val |= CIF_ISP_CTRL_ISP_CFG_UPD | CIF_ISP_CTRL_ISP_ENABLE | |
|---|
| 1650 | 2185 | CIF_ISP_CTRL_ISP_INFORM_ENABLE | CIF_ISP_CTRL_ISP_CFG_UPD_PERMANENT; |
|---|
| 1651 | 2186 | if (dev->isp_ver == ISP_V20) |
|---|
| 1652 | 2187 | val |= NOC_HURRY_PRIORITY(2) | NOC_HURRY_W_MODE(2) | NOC_HURRY_R_MODE(1); |
|---|
| 1653 | 2188 | if (atomic_read(&dev->hw_dev->refcnt) > 1) |
|---|
| 1654 | 2189 | is_direct = false; |
|---|
| 1655 | | - rkisp_write(dev, CIF_ISP_CTRL, val, is_direct); |
|---|
| 2190 | + rkisp_unite_write(dev, CIF_ISP_CTRL, val, is_direct, dev->hw_dev->is_unite); |
|---|
| 2191 | + rkisp_clear_reg_cache_bits(dev, CIF_ISP_CTRL, CIF_ISP_CTRL_ISP_CFG_UPD); |
|---|
| 1656 | 2192 | |
|---|
| 1657 | 2193 | dev->isp_err_cnt = 0; |
|---|
| 1658 | 2194 | dev->isp_isr_cnt = 0; |
|---|
| 1659 | 2195 | dev->isp_state = ISP_START | ISP_FRAME_END; |
|---|
| 1660 | | - dev->irq_ends_mask |= ISP_FRAME_END | ISP_FRAME_IN; |
|---|
| 2196 | + dev->irq_ends_mask |= ISP_FRAME_END; |
|---|
| 1661 | 2197 | dev->irq_ends = 0; |
|---|
| 1662 | 2198 | |
|---|
| 1663 | 2199 | /* XXX: Is the 1000us too long? |
|---|
| .. | .. |
|---|
| 2097 | 2633 | struct rkisp_isp_subdev *isp_sd = sd_to_isp_sd(sd); |
|---|
| 2098 | 2634 | struct rkisp_device *dev = sd_to_isp_dev(sd); |
|---|
| 2099 | 2635 | struct v4l2_rect *crop; |
|---|
| 2100 | | - u32 max_w, max_h; |
|---|
| 2636 | + u32 max_w, max_h, max_size; |
|---|
| 2101 | 2637 | |
|---|
| 2102 | 2638 | if (!sel) |
|---|
| 2103 | 2639 | goto err; |
|---|
| .. | .. |
|---|
| 2118 | 2654 | crop->left = 0; |
|---|
| 2119 | 2655 | crop->top = 0; |
|---|
| 2120 | 2656 | if (sel->pad == RKISP_ISP_PAD_SINK) { |
|---|
| 2121 | | - if (dev->isp_ver == ISP_V12) { |
|---|
| 2657 | + switch (dev->isp_ver) { |
|---|
| 2658 | + case ISP_V12: |
|---|
| 2122 | 2659 | max_w = CIF_ISP_INPUT_W_MAX_V12; |
|---|
| 2123 | 2660 | max_h = CIF_ISP_INPUT_H_MAX_V12; |
|---|
| 2124 | | - } else if (dev->isp_ver == ISP_V13) { |
|---|
| 2661 | + break; |
|---|
| 2662 | + case ISP_V13: |
|---|
| 2125 | 2663 | max_w = CIF_ISP_INPUT_W_MAX_V13; |
|---|
| 2126 | 2664 | max_h = CIF_ISP_INPUT_H_MAX_V13; |
|---|
| 2127 | | - } else if (dev->isp_ver == ISP_V21) { |
|---|
| 2665 | + break; |
|---|
| 2666 | + case ISP_V21: |
|---|
| 2128 | 2667 | max_w = CIF_ISP_INPUT_W_MAX_V21; |
|---|
| 2129 | 2668 | max_h = CIF_ISP_INPUT_H_MAX_V21; |
|---|
| 2130 | | - } else { |
|---|
| 2669 | + break; |
|---|
| 2670 | + case ISP_V30: |
|---|
| 2671 | + max_w = dev->hw_dev->is_unite ? |
|---|
| 2672 | + CIF_ISP_INPUT_W_MAX_V30_UNITE : CIF_ISP_INPUT_W_MAX_V30; |
|---|
| 2673 | + max_h = dev->hw_dev->is_unite ? |
|---|
| 2674 | + CIF_ISP_INPUT_H_MAX_V30_UNITE : CIF_ISP_INPUT_H_MAX_V30; |
|---|
| 2675 | + break; |
|---|
| 2676 | + case ISP_V32: |
|---|
| 2677 | + max_w = CIF_ISP_INPUT_W_MAX_V32; |
|---|
| 2678 | + max_h = CIF_ISP_INPUT_H_MAX_V32; |
|---|
| 2679 | + break; |
|---|
| 2680 | + case ISP_V32_L: |
|---|
| 2681 | + max_w = CIF_ISP_INPUT_W_MAX_V32_L; |
|---|
| 2682 | + max_h = CIF_ISP_INPUT_H_MAX_V32_L; |
|---|
| 2683 | + break; |
|---|
| 2684 | + default: |
|---|
| 2131 | 2685 | max_w = CIF_ISP_INPUT_W_MAX; |
|---|
| 2132 | 2686 | max_h = CIF_ISP_INPUT_H_MAX; |
|---|
| 2133 | 2687 | } |
|---|
| 2688 | + max_size = max_w * max_h; |
|---|
| 2689 | + max_h = max_size / isp_sd->in_frm.width; |
|---|
| 2690 | + |
|---|
| 2134 | 2691 | crop->width = min_t(u32, isp_sd->in_frm.width, max_w); |
|---|
| 2135 | 2692 | crop->height = min_t(u32, isp_sd->in_frm.height, max_h); |
|---|
| 2136 | 2693 | } |
|---|
| .. | .. |
|---|
| 2146 | 2703 | return 0; |
|---|
| 2147 | 2704 | err: |
|---|
| 2148 | 2705 | return -EINVAL; |
|---|
| 2706 | +} |
|---|
| 2707 | + |
|---|
| 2708 | +static void rkisp_check_stream_dcrop(struct rkisp_device *dev, |
|---|
| 2709 | + struct v4l2_rect *crop) |
|---|
| 2710 | +{ |
|---|
| 2711 | + struct rkisp_stream *stream; |
|---|
| 2712 | + struct v4l2_rect *dcrop; |
|---|
| 2713 | + u32 i; |
|---|
| 2714 | + |
|---|
| 2715 | + for (i = 0; i < RKISP_MAX_STREAM; i++) { |
|---|
| 2716 | + if (i != RKISP_STREAM_MP && i != RKISP_STREAM_SP && |
|---|
| 2717 | + i != RKISP_STREAM_FBC && i != RKISP_STREAM_BP) |
|---|
| 2718 | + continue; |
|---|
| 2719 | + stream = &dev->cap_dev.stream[i]; |
|---|
| 2720 | + dcrop = &stream->dcrop; |
|---|
| 2721 | + v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, |
|---|
| 2722 | + "%s id:%d %dx%d(%d %d) from %dx%d(%d %d)\n", |
|---|
| 2723 | + __func__, i, |
|---|
| 2724 | + dcrop->width, dcrop->height, dcrop->left, dcrop->top, |
|---|
| 2725 | + crop->width, crop->height, crop->left, crop->top); |
|---|
| 2726 | + /* make sure dcrop window in isp output window */ |
|---|
| 2727 | + if (dcrop->width > crop->width) { |
|---|
| 2728 | + dcrop->width = crop->width; |
|---|
| 2729 | + dcrop->left = 0; |
|---|
| 2730 | + } else if ((dcrop->left + dcrop->width) > crop->width) { |
|---|
| 2731 | + dcrop->left = crop->width - dcrop->width; |
|---|
| 2732 | + } |
|---|
| 2733 | + if (dcrop->height > crop->height) { |
|---|
| 2734 | + dcrop->height = crop->height; |
|---|
| 2735 | + dcrop->top = 0; |
|---|
| 2736 | + } else if ((dcrop->top + dcrop->height) > crop->height) { |
|---|
| 2737 | + dcrop->top = crop->height - dcrop->height; |
|---|
| 2738 | + } |
|---|
| 2739 | + } |
|---|
| 2149 | 2740 | } |
|---|
| 2150 | 2741 | |
|---|
| 2151 | 2742 | static int rkisp_isp_sd_set_selection(struct v4l2_subdev *sd, |
|---|
| .. | .. |
|---|
| 2179 | 2770 | |
|---|
| 2180 | 2771 | if (sel->pad == RKISP_ISP_PAD_SINK) { |
|---|
| 2181 | 2772 | isp_sd->in_crop = *crop; |
|---|
| 2182 | | - /* ISP20 don't have out crop */ |
|---|
| 2183 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) { |
|---|
| 2773 | + /* don't have out crop */ |
|---|
| 2774 | + if (dev->isp_ver >= ISP_V20) { |
|---|
| 2184 | 2775 | isp_sd->out_crop = *crop; |
|---|
| 2185 | 2776 | isp_sd->out_crop.left = 0; |
|---|
| 2186 | 2777 | isp_sd->out_crop.top = 0; |
|---|
| 2187 | 2778 | dev->br_dev.crop = isp_sd->out_crop; |
|---|
| 2188 | 2779 | } |
|---|
| 2189 | 2780 | } else { |
|---|
| 2190 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) |
|---|
| 2781 | + if (dev->isp_ver >= ISP_V20) |
|---|
| 2191 | 2782 | *crop = isp_sd->out_crop; |
|---|
| 2192 | 2783 | isp_sd->out_crop = *crop; |
|---|
| 2193 | 2784 | } |
|---|
| 2785 | + |
|---|
| 2786 | + rkisp_check_stream_dcrop(dev, crop); |
|---|
| 2194 | 2787 | |
|---|
| 2195 | 2788 | return 0; |
|---|
| 2196 | 2789 | err: |
|---|
| .. | .. |
|---|
| 2246 | 2839 | struct rkisp_stream *stream; |
|---|
| 2247 | 2840 | int i; |
|---|
| 2248 | 2841 | |
|---|
| 2842 | + rkisp_stats_first_ddr_config(&dev->stats_vdev); |
|---|
| 2249 | 2843 | if (dev->hw_dev->is_mi_update) |
|---|
| 2250 | 2844 | return; |
|---|
| 2251 | 2845 | |
|---|
| 2252 | | - rkisp_stats_first_ddr_config(&dev->stats_vdev); |
|---|
| 2253 | 2846 | rkisp_config_dmatx_valid_buf(dev); |
|---|
| 2254 | 2847 | |
|---|
| 2255 | 2848 | force_cfg_update(dev); |
|---|
| 2256 | 2849 | |
|---|
| 2257 | 2850 | hdr_update_dmatx_buf(dev); |
|---|
| 2258 | | - if (dev->br_dev.en && dev->isp_ver == ISP_V20) { |
|---|
| 2259 | | - stream = &dev->cap_dev.stream[RKISP_STREAM_SP]; |
|---|
| 2260 | | - rkisp_update_spstream_buf(stream); |
|---|
| 2261 | | - } |
|---|
| 2262 | 2851 | if (dev->hw_dev->is_single) { |
|---|
| 2263 | 2852 | for (i = 0; i < RKISP_MAX_STREAM; i++) { |
|---|
| 2264 | 2853 | stream = &dev->cap_dev.stream[i]; |
|---|
| 2265 | | - if (stream->streaming && !stream->next_buf) |
|---|
| 2266 | | - stream->ops->frame_end(stream); |
|---|
| 2854 | + if (stream->id == RKISP_STREAM_VIR || |
|---|
| 2855 | + stream->id == RKISP_STREAM_LUMA) |
|---|
| 2856 | + continue; |
|---|
| 2857 | + if (stream->streaming && !stream->curr_buf) |
|---|
| 2858 | + stream->ops->frame_end(stream, FRAME_INIT); |
|---|
| 2267 | 2859 | } |
|---|
| 2268 | 2860 | } |
|---|
| 2861 | + rkisp_stats_next_ddr_config(&dev->stats_vdev); |
|---|
| 2269 | 2862 | } |
|---|
| 2270 | 2863 | |
|---|
| 2271 | 2864 | static int rkisp_isp_sd_s_stream(struct v4l2_subdev *sd, int on) |
|---|
| 2272 | 2865 | { |
|---|
| 2273 | 2866 | struct rkisp_device *isp_dev = sd_to_isp_dev(sd); |
|---|
| 2867 | + struct rkisp_hw_dev *hw_dev = isp_dev->hw_dev; |
|---|
| 2274 | 2868 | |
|---|
| 2275 | 2869 | if (!on) { |
|---|
| 2870 | + if (IS_HDR_RDBK(isp_dev->rd_mode)) { |
|---|
| 2871 | + struct rkisp_stream *s; |
|---|
| 2872 | + int i; |
|---|
| 2873 | + |
|---|
| 2874 | + for (i = RKISP_STREAM_RAWRD0; i <= RKISP_STREAM_RAWRD2; i++) { |
|---|
| 2875 | + s = &isp_dev->dmarx_dev.stream[i]; |
|---|
| 2876 | + if (s->stopping) |
|---|
| 2877 | + wake_up(&s->done); |
|---|
| 2878 | + } |
|---|
| 2879 | + } |
|---|
| 2276 | 2880 | wait_event_timeout(isp_dev->sync_onoff, |
|---|
| 2277 | | - isp_dev->irq_ends_mask == (ISP_FRAME_END | ISP_FRAME_IN) && |
|---|
| 2278 | | - (!IS_HDR_RDBK(isp_dev->rd_mode) || |
|---|
| 2279 | | - isp_dev->isp_state & ISP_STOP), msecs_to_jiffies(5)); |
|---|
| 2881 | + isp_dev->isp_state & ISP_STOP || |
|---|
| 2882 | + !IS_HDR_RDBK(isp_dev->rd_mode), |
|---|
| 2883 | + msecs_to_jiffies(50)); |
|---|
| 2280 | 2884 | rkisp_isp_stop(isp_dev); |
|---|
| 2281 | | - atomic_dec(&isp_dev->hw_dev->refcnt); |
|---|
| 2885 | + atomic_dec(&hw_dev->refcnt); |
|---|
| 2282 | 2886 | rkisp_params_stream_stop(&isp_dev->params_vdev); |
|---|
| 2887 | + atomic_set(&isp_dev->isp_sdev.frm_sync_seq, 0); |
|---|
| 2283 | 2888 | rkisp_stop_3a_run(isp_dev); |
|---|
| 2284 | 2889 | return 0; |
|---|
| 2285 | 2890 | } |
|---|
| 2286 | 2891 | |
|---|
| 2892 | + hw_dev->is_runing = true; |
|---|
| 2287 | 2893 | rkisp_start_3a_run(isp_dev); |
|---|
| 2288 | 2894 | memset(&isp_dev->isp_sdev.dbg, 0, sizeof(isp_dev->isp_sdev.dbg)); |
|---|
| 2289 | | - atomic_inc(&isp_dev->hw_dev->refcnt); |
|---|
| 2290 | | - atomic_set(&isp_dev->isp_sdev.frm_sync_seq, 0); |
|---|
| 2291 | | - rkisp_global_update_mi(isp_dev); |
|---|
| 2895 | + if (atomic_inc_return(&hw_dev->refcnt) > hw_dev->dev_link_num) { |
|---|
| 2896 | + dev_err(isp_dev->dev, "%s fail: input link before hw start\n", __func__); |
|---|
| 2897 | + atomic_dec(&hw_dev->refcnt); |
|---|
| 2898 | + return -EINVAL; |
|---|
| 2899 | + } |
|---|
| 2900 | + |
|---|
| 2292 | 2901 | rkisp_config_cif(isp_dev); |
|---|
| 2293 | 2902 | rkisp_isp_start(isp_dev); |
|---|
| 2903 | + rkisp_global_update_mi(isp_dev); |
|---|
| 2294 | 2904 | rkisp_rdbk_trigger_event(isp_dev, T_CMD_QUEUE, NULL); |
|---|
| 2295 | 2905 | return 0; |
|---|
| 2906 | +} |
|---|
| 2907 | + |
|---|
| 2908 | +static void rkisp_rx_buf_free(struct rkisp_device *dev, struct rkisp_rx_buf *dbufs) |
|---|
| 2909 | +{ |
|---|
| 2910 | + const struct vb2_mem_ops *g_ops = dev->hw_dev->mem_ops; |
|---|
| 2911 | + struct rkisp_rx_buf_pool *pool; |
|---|
| 2912 | + int i = 0; |
|---|
| 2913 | + |
|---|
| 2914 | + if (!dbufs) |
|---|
| 2915 | + return; |
|---|
| 2916 | + |
|---|
| 2917 | + for (i = 0; i < RKISP_RX_BUF_POOL_MAX; i++) { |
|---|
| 2918 | + pool = &dev->pv_pool[i]; |
|---|
| 2919 | + if (dbufs == pool->dbufs) { |
|---|
| 2920 | + if (pool->mem_priv) { |
|---|
| 2921 | + g_ops->unmap_dmabuf(pool->mem_priv); |
|---|
| 2922 | + g_ops->detach_dmabuf(pool->mem_priv); |
|---|
| 2923 | + dma_buf_put(pool->dbufs->dbuf); |
|---|
| 2924 | + pool->mem_priv = NULL; |
|---|
| 2925 | + } |
|---|
| 2926 | + pool->dbufs = NULL; |
|---|
| 2927 | + break; |
|---|
| 2928 | + } |
|---|
| 2929 | + } |
|---|
| 2930 | +} |
|---|
| 2931 | + |
|---|
| 2932 | +static void rkisp_rx_qbuf_online(struct rkisp_stream *stream, |
|---|
| 2933 | + struct rkisp_rx_buf_pool *pool) |
|---|
| 2934 | +{ |
|---|
| 2935 | + struct rkisp_device *dev = stream->ispdev; |
|---|
| 2936 | + u32 val = pool->buf.buff_addr[RKISP_PLANE_Y]; |
|---|
| 2937 | + |
|---|
| 2938 | + rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false); |
|---|
| 2939 | + if (dev->hw_dev->is_unite) { |
|---|
| 2940 | + u32 offs = stream->out_fmt.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL; |
|---|
| 2941 | + |
|---|
| 2942 | + if (stream->memory) |
|---|
| 2943 | + offs *= DIV_ROUND_UP(stream->out_isp_fmt.bpp[0], 8); |
|---|
| 2944 | + else |
|---|
| 2945 | + offs = offs * stream->out_isp_fmt.bpp[0] / 8; |
|---|
| 2946 | + val += offs; |
|---|
| 2947 | + rkisp_next_write(dev, stream->config->mi.y_base_ad_init, val, false); |
|---|
| 2948 | + } |
|---|
| 2949 | +} |
|---|
| 2950 | + |
|---|
| 2951 | +static void rkisp_rx_qbuf_rdbk(struct rkisp_stream *stream, |
|---|
| 2952 | + struct rkisp_rx_buf_pool *pool) |
|---|
| 2953 | +{ |
|---|
| 2954 | + struct rkisp_device *dev = stream->ispdev; |
|---|
| 2955 | + unsigned long lock_flags = 0; |
|---|
| 2956 | + struct rkisp_buffer *ispbuf = &pool->buf; |
|---|
| 2957 | + struct isp2x_csi_trigger trigger = { |
|---|
| 2958 | + .frame_timestamp = ispbuf->vb.vb2_buf.timestamp, |
|---|
| 2959 | + .sof_timestamp = ispbuf->vb.vb2_buf.timestamp, |
|---|
| 2960 | + .frame_id = ispbuf->vb.sequence, |
|---|
| 2961 | + .mode = 0, |
|---|
| 2962 | + .times = 0, |
|---|
| 2963 | + }; |
|---|
| 2964 | + spin_lock_irqsave(&stream->vbq_lock, lock_flags); |
|---|
| 2965 | + if (list_empty(&stream->buf_queue) && !stream->curr_buf) { |
|---|
| 2966 | + stream->curr_buf = ispbuf; |
|---|
| 2967 | + stream->ops->update_mi(stream); |
|---|
| 2968 | + } else { |
|---|
| 2969 | + list_add_tail(&ispbuf->queue, &stream->buf_queue); |
|---|
| 2970 | + } |
|---|
| 2971 | + spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); |
|---|
| 2972 | + if (stream->id == RKISP_STREAM_RAWRD2) |
|---|
| 2973 | + rkisp_rdbk_trigger_event(dev, T_CMD_QUEUE, &trigger); |
|---|
| 2974 | +} |
|---|
| 2975 | + |
|---|
| 2976 | +static int rkisp_rx_qbuf(struct rkisp_device *dev, |
|---|
| 2977 | + struct rkisp_rx_buf *dbufs) |
|---|
| 2978 | +{ |
|---|
| 2979 | + struct rkisp_stream *stream; |
|---|
| 2980 | + struct rkisp_rx_buf_pool *pool; |
|---|
| 2981 | + int i; |
|---|
| 2982 | + |
|---|
| 2983 | + for (i = 0; i < RKISP_RX_BUF_POOL_MAX; i++) { |
|---|
| 2984 | + pool = &dev->pv_pool[i]; |
|---|
| 2985 | + if (dbufs == pool->dbufs) |
|---|
| 2986 | + break; |
|---|
| 2987 | + } |
|---|
| 2988 | + |
|---|
| 2989 | + if (pool->dbufs == NULL || pool->dbufs != dbufs) |
|---|
| 2990 | + return -EINVAL; |
|---|
| 2991 | + switch (dbufs->type) { |
|---|
| 2992 | + case BUF_SHORT: |
|---|
| 2993 | + stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD2]; |
|---|
| 2994 | + break; |
|---|
| 2995 | + case BUF_MIDDLE: |
|---|
| 2996 | + stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD0]; |
|---|
| 2997 | + break; |
|---|
| 2998 | + case BUF_LONG: |
|---|
| 2999 | + default: |
|---|
| 3000 | + stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD1]; |
|---|
| 3001 | + } |
|---|
| 3002 | + |
|---|
| 3003 | + v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, |
|---|
| 3004 | + "%s rd_mode:%d seq:%d dma:0x%x\n", |
|---|
| 3005 | + __func__, dev->rd_mode, dbufs->sequence, |
|---|
| 3006 | + pool->buf.buff_addr[RKISP_PLANE_Y]); |
|---|
| 3007 | + |
|---|
| 3008 | + if (!IS_HDR_RDBK(dev->rd_mode)) { |
|---|
| 3009 | + rkisp_rx_qbuf_online(stream, pool); |
|---|
| 3010 | + } else { |
|---|
| 3011 | + pool->buf.vb.vb2_buf.timestamp = dbufs->timestamp; |
|---|
| 3012 | + pool->buf.vb.sequence = dbufs->sequence; |
|---|
| 3013 | + rkisp_rx_qbuf_rdbk(stream, pool); |
|---|
| 3014 | + } |
|---|
| 3015 | + return 0; |
|---|
| 3016 | +} |
|---|
| 3017 | + |
|---|
| 3018 | +void rkisp_rx_buf_pool_free(struct rkisp_device *dev) |
|---|
| 3019 | +{ |
|---|
| 3020 | + const struct vb2_mem_ops *g_ops = dev->hw_dev->mem_ops; |
|---|
| 3021 | + struct rkisp_rx_buf_pool *pool; |
|---|
| 3022 | + int i; |
|---|
| 3023 | + |
|---|
| 3024 | + for (i = 0; i < RKISP_RX_BUF_POOL_MAX; i++) { |
|---|
| 3025 | + pool = &dev->pv_pool[i]; |
|---|
| 3026 | + if (!pool->dbufs) |
|---|
| 3027 | + break; |
|---|
| 3028 | + if (pool->mem_priv) { |
|---|
| 3029 | + g_ops->unmap_dmabuf(pool->mem_priv); |
|---|
| 3030 | + g_ops->detach_dmabuf(pool->mem_priv); |
|---|
| 3031 | + dma_buf_put(pool->dbufs->dbuf); |
|---|
| 3032 | + pool->mem_priv = NULL; |
|---|
| 3033 | + } |
|---|
| 3034 | + pool->dbufs = NULL; |
|---|
| 3035 | + } |
|---|
| 3036 | +} |
|---|
| 3037 | + |
|---|
| 3038 | +static int rkisp_rx_buf_pool_init(struct rkisp_device *dev, |
|---|
| 3039 | + struct rkisp_rx_buf *dbufs) |
|---|
| 3040 | +{ |
|---|
| 3041 | + const struct vb2_mem_ops *g_ops = dev->hw_dev->mem_ops; |
|---|
| 3042 | + struct rkisp_stream *stream; |
|---|
| 3043 | + struct rkisp_rx_buf_pool *pool; |
|---|
| 3044 | + struct sg_table *sg_tbl; |
|---|
| 3045 | + dma_addr_t dma; |
|---|
| 3046 | + int i, ret; |
|---|
| 3047 | + void *mem, *vaddr = NULL; |
|---|
| 3048 | + |
|---|
| 3049 | + for (i = 0; i < RKISP_RX_BUF_POOL_MAX; i++) { |
|---|
| 3050 | + pool = &dev->pv_pool[i]; |
|---|
| 3051 | + if (!pool->dbufs) |
|---|
| 3052 | + break; |
|---|
| 3053 | + } |
|---|
| 3054 | + |
|---|
| 3055 | + pool->dbufs = dbufs; |
|---|
| 3056 | + v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, |
|---|
| 3057 | + "%s type:0x%x dbufs[%d]:%p", __func__, dbufs->type, i, dbufs); |
|---|
| 3058 | + |
|---|
| 3059 | + if (dbufs->is_resmem) { |
|---|
| 3060 | + dma = dbufs->dma; |
|---|
| 3061 | + goto end; |
|---|
| 3062 | + } |
|---|
| 3063 | + mem = g_ops->attach_dmabuf(dev->hw_dev->dev, dbufs->dbuf, |
|---|
| 3064 | + dbufs->dbuf->size, DMA_BIDIRECTIONAL); |
|---|
| 3065 | + if (IS_ERR(mem)) { |
|---|
| 3066 | + ret = PTR_ERR(mem); |
|---|
| 3067 | + goto err; |
|---|
| 3068 | + } |
|---|
| 3069 | + pool->mem_priv = mem; |
|---|
| 3070 | + ret = g_ops->map_dmabuf(mem); |
|---|
| 3071 | + if (ret) |
|---|
| 3072 | + goto err; |
|---|
| 3073 | + if (dev->hw_dev->is_dma_sg_ops) { |
|---|
| 3074 | + sg_tbl = (struct sg_table *)g_ops->cookie(mem); |
|---|
| 3075 | + dma = sg_dma_address(sg_tbl->sgl); |
|---|
| 3076 | + } else { |
|---|
| 3077 | + dma = *((dma_addr_t *)g_ops->cookie(mem)); |
|---|
| 3078 | + } |
|---|
| 3079 | + get_dma_buf(dbufs->dbuf); |
|---|
| 3080 | + vaddr = g_ops->vaddr(mem); |
|---|
| 3081 | +end: |
|---|
| 3082 | + dbufs->is_init = true; |
|---|
| 3083 | + pool->buf.other = dbufs; |
|---|
| 3084 | + pool->buf.buff_addr[RKISP_PLANE_Y] = dma; |
|---|
| 3085 | + pool->buf.vaddr[RKISP_PLANE_Y] = vaddr; |
|---|
| 3086 | + |
|---|
| 3087 | + switch (dbufs->type) { |
|---|
| 3088 | + case BUF_SHORT: |
|---|
| 3089 | + stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD2]; |
|---|
| 3090 | + break; |
|---|
| 3091 | + case BUF_MIDDLE: |
|---|
| 3092 | + stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD0]; |
|---|
| 3093 | + break; |
|---|
| 3094 | + case BUF_LONG: |
|---|
| 3095 | + default: |
|---|
| 3096 | + stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD1]; |
|---|
| 3097 | + } |
|---|
| 3098 | + if (dbufs->is_first) { |
|---|
| 3099 | + stream->memory = 0; |
|---|
| 3100 | + if (dbufs->is_uncompact) |
|---|
| 3101 | + stream->memory = SW_CSI_RAW_WR_SIMG_MODE; |
|---|
| 3102 | + rkisp_dmarx_set_fmt(stream, stream->out_fmt); |
|---|
| 3103 | + stream->ops->config_mi(stream); |
|---|
| 3104 | + dbufs->is_first = false; |
|---|
| 3105 | + } |
|---|
| 3106 | + v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, |
|---|
| 3107 | + "%s dma:0x%x vaddr:%p", __func__, (u32)dma, vaddr); |
|---|
| 3108 | + return 0; |
|---|
| 3109 | +err: |
|---|
| 3110 | + rkisp_rx_buf_pool_free(dev); |
|---|
| 3111 | + return ret; |
|---|
| 3112 | +} |
|---|
| 3113 | + |
|---|
| 3114 | +static int rkisp_sd_s_rx_buffer(struct v4l2_subdev *sd, |
|---|
| 3115 | + void *buf, unsigned int *size) |
|---|
| 3116 | +{ |
|---|
| 3117 | + struct rkisp_device *dev = sd_to_isp_dev(sd); |
|---|
| 3118 | + struct rkisp_rx_buf *dbufs; |
|---|
| 3119 | + int ret = 0; |
|---|
| 3120 | + |
|---|
| 3121 | + if (!buf) |
|---|
| 3122 | + return -EINVAL; |
|---|
| 3123 | + |
|---|
| 3124 | + dbufs = buf; |
|---|
| 3125 | + if (!dbufs->is_init) |
|---|
| 3126 | + ret = rkisp_rx_buf_pool_init(dev, dbufs); |
|---|
| 3127 | + if (!ret) |
|---|
| 3128 | + ret = rkisp_rx_qbuf(dev, dbufs); |
|---|
| 3129 | + |
|---|
| 3130 | + return ret; |
|---|
| 2296 | 3131 | } |
|---|
| 2297 | 3132 | |
|---|
| 2298 | 3133 | static int rkisp_isp_sd_s_power(struct v4l2_subdev *sd, int on) |
|---|
| .. | .. |
|---|
| 2300 | 3135 | struct rkisp_device *isp_dev = sd_to_isp_dev(sd); |
|---|
| 2301 | 3136 | int ret; |
|---|
| 2302 | 3137 | |
|---|
| 2303 | | - if (isp_dev->hw_dev->is_thunderboot) |
|---|
| 2304 | | - return 0; |
|---|
| 2305 | | - |
|---|
| 2306 | 3138 | v4l2_dbg(1, rkisp_debug, &isp_dev->v4l2_dev, |
|---|
| 2307 | 3139 | "%s on:%d\n", __func__, on); |
|---|
| 2308 | 3140 | |
|---|
| 2309 | 3141 | if (on) { |
|---|
| 2310 | | - if (isp_dev->isp_ver == ISP_V20 || isp_dev->isp_ver == ISP_V21) |
|---|
| 3142 | + if (isp_dev->isp_ver >= ISP_V20) |
|---|
| 2311 | 3143 | kfifo_reset(&isp_dev->rdbk_kfifo); |
|---|
| 2312 | 3144 | ret = pm_runtime_get_sync(isp_dev->dev); |
|---|
| 2313 | 3145 | } else { |
|---|
| .. | .. |
|---|
| 2337 | 3169 | dev = sd_to_isp_dev(sd); |
|---|
| 2338 | 3170 | if (!dev) |
|---|
| 2339 | 3171 | return -ENODEV; |
|---|
| 3172 | + |
|---|
| 3173 | + if (dev->hw_dev->is_runing && |
|---|
| 3174 | + (!dev->isp_inp || |
|---|
| 3175 | + !(dev->isp_inp & ~rawrd) || |
|---|
| 3176 | + !strcmp(remote->entity->name, CSI_DEV_NAME) || |
|---|
| 3177 | + strstr(remote->entity->name, "rkcif"))) { |
|---|
| 3178 | + v4l2_err(sd, "no support link for isp hw working\n"); |
|---|
| 3179 | + return -EINVAL; |
|---|
| 3180 | + } |
|---|
| 2340 | 3181 | |
|---|
| 2341 | 3182 | if (!strcmp(remote->entity->name, DMA_VDEV_NAME)) { |
|---|
| 2342 | 3183 | stream = &dev->dmarx_dev.stream[RKISP_STREAM_DMARX]; |
|---|
| .. | .. |
|---|
| 2386 | 3227 | } else { |
|---|
| 2387 | 3228 | dev->isp_inp &= ~INP_RAWRD2; |
|---|
| 2388 | 3229 | } |
|---|
| 3230 | + } else if (!strcmp(remote->entity->name, FBC_VDEV_NAME)) { |
|---|
| 3231 | + stream = &dev->cap_dev.stream[RKISP_STREAM_FBC]; |
|---|
| 3232 | + } else if (!strcmp(remote->entity->name, BP_VDEV_NAME)) { |
|---|
| 3233 | + stream = &dev->cap_dev.stream[RKISP_STREAM_BP]; |
|---|
| 3234 | + } else if (!strcmp(remote->entity->name, MPDS_VDEV_NAME)) { |
|---|
| 3235 | + stream = &dev->cap_dev.stream[RKISP_STREAM_MPDS]; |
|---|
| 3236 | + } else if (!strcmp(remote->entity->name, BPDS_VDEV_NAME)) { |
|---|
| 3237 | + stream = &dev->cap_dev.stream[RKISP_STREAM_BPDS]; |
|---|
| 3238 | + } else if (!strcmp(remote->entity->name, LUMA_VDEV_NAME)) { |
|---|
| 3239 | + stream = &dev->cap_dev.stream[RKISP_STREAM_LUMA]; |
|---|
| 3240 | + } else if (!strcmp(remote->entity->name, VIR_VDEV_NAME)) { |
|---|
| 3241 | + stream = &dev->cap_dev.stream[RKISP_STREAM_VIR]; |
|---|
| 2389 | 3242 | } else if (!strcmp(remote->entity->name, SP_VDEV_NAME)) { |
|---|
| 2390 | 3243 | stream = &dev->cap_dev.stream[RKISP_STREAM_SP]; |
|---|
| 2391 | 3244 | } else if (!strcmp(remote->entity->name, MP_VDEV_NAME)) { |
|---|
| .. | .. |
|---|
| 2430 | 3283 | |
|---|
| 2431 | 3284 | if (stream) |
|---|
| 2432 | 3285 | stream->linked = flags & MEDIA_LNK_FL_ENABLED; |
|---|
| 2433 | | - if (dev->isp_inp & rawrd) |
|---|
| 3286 | + if (dev->isp_inp & rawrd) { |
|---|
| 2434 | 3287 | dev->dmarx_dev.trigger = T_MANUAL; |
|---|
| 2435 | | - else |
|---|
| 3288 | + dev->is_rdbk_auto = false; |
|---|
| 3289 | + } else { |
|---|
| 2436 | 3290 | dev->dmarx_dev.trigger = T_AUTO; |
|---|
| 3291 | + } |
|---|
| 3292 | + if (dev->isp_inp & INP_CIF) { |
|---|
| 3293 | + struct v4l2_subdev *remote = get_remote_sensor(sd); |
|---|
| 3294 | + struct rkisp_vicap_mode mode; |
|---|
| 2437 | 3295 | |
|---|
| 3296 | + memset(&mode, 0, sizeof(mode)); |
|---|
| 3297 | + mode.name = dev->name; |
|---|
| 3298 | + mode.rdbk_mode = !!(dev->isp_inp & rawrd); |
|---|
| 3299 | + /* read back mode only */ |
|---|
| 3300 | + if (dev->isp_ver < ISP_V30 || !dev->hw_dev->is_single) |
|---|
| 3301 | + mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ; |
|---|
| 3302 | + v4l2_subdev_call(remote, core, ioctl, |
|---|
| 3303 | + RKISP_VICAP_CMD_MODE, &mode); |
|---|
| 3304 | + dev->vicap_in = mode.input; |
|---|
| 3305 | + } |
|---|
| 3306 | + |
|---|
| 3307 | + if (!dev->isp_inp) |
|---|
| 3308 | + dev->is_hw_link = false; |
|---|
| 3309 | + else |
|---|
| 3310 | + dev->is_hw_link = true; |
|---|
| 2438 | 3311 | v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, |
|---|
| 2439 | 3312 | "isp input:0x%x\n", dev->isp_inp); |
|---|
| 2440 | 3313 | return 0; |
|---|
| .. | .. |
|---|
| 2482 | 3355 | atomic_inc_return(&isp->frm_sync_seq) - 1, |
|---|
| 2483 | 3356 | }; |
|---|
| 2484 | 3357 | |
|---|
| 2485 | | - event.timestamp = ns_to_timespec(ktime_get_ns()); |
|---|
| 2486 | 3358 | v4l2_event_queue(isp->sd.devnode, &event); |
|---|
| 2487 | 3359 | } |
|---|
| 2488 | 3360 | |
|---|
| .. | .. |
|---|
| 2499 | 3371 | return v4l2_event_subscribe(fh, sub, ISP_V4L2_EVENT_ELEMS, NULL); |
|---|
| 2500 | 3372 | } |
|---|
| 2501 | 3373 | |
|---|
| 3374 | +static int rkisp_get_info(struct rkisp_device *dev, struct rkisp_isp_info *info) |
|---|
| 3375 | +{ |
|---|
| 3376 | + struct v4l2_rect *in_crop = &dev->isp_sdev.in_crop; |
|---|
| 3377 | + u32 rd_mode, mode = 0, bit = 0; |
|---|
| 3378 | + int ret; |
|---|
| 3379 | + |
|---|
| 3380 | + if (!(dev->isp_state & ISP_START)) { |
|---|
| 3381 | + struct rkmodule_hdr_cfg cfg; |
|---|
| 3382 | + |
|---|
| 3383 | + ret = rkisp_csi_get_hdr_cfg(dev, &cfg); |
|---|
| 3384 | + if (ret) |
|---|
| 3385 | + return ret; |
|---|
| 3386 | + rd_mode = cfg.hdr_mode; |
|---|
| 3387 | + if (rd_mode == HDR_COMPR) |
|---|
| 3388 | + bit = cfg.compr.bit > 20 ? 20 : cfg.compr.bit; |
|---|
| 3389 | + } else { |
|---|
| 3390 | + rd_mode = dev->rd_mode; |
|---|
| 3391 | + bit = dev->hdr.compr_bit; |
|---|
| 3392 | + } |
|---|
| 3393 | + |
|---|
| 3394 | + switch (rd_mode) { |
|---|
| 3395 | + case HDR_RDBK_FRAME2: |
|---|
| 3396 | + case HDR_FRAMEX2_DDR: |
|---|
| 3397 | + case HDR_LINEX2_DDR: |
|---|
| 3398 | + mode = RKISP_ISP_HDR2; |
|---|
| 3399 | + break; |
|---|
| 3400 | + case HDR_RDBK_FRAME3: |
|---|
| 3401 | + case HDR_FRAMEX3_DDR: |
|---|
| 3402 | + case HDR_LINEX3_DDR: |
|---|
| 3403 | + mode = RKISP_ISP_HDR3; |
|---|
| 3404 | + break; |
|---|
| 3405 | + default: |
|---|
| 3406 | + mode = RKISP_ISP_NORMAL; |
|---|
| 3407 | + } |
|---|
| 3408 | + if (bit) |
|---|
| 3409 | + mode = RKISP_ISP_COMPR; |
|---|
| 3410 | + info->compr_bit = bit; |
|---|
| 3411 | + |
|---|
| 3412 | + if (dev->is_bigmode) |
|---|
| 3413 | + mode |= RKISP_ISP_BIGMODE; |
|---|
| 3414 | + info->mode = mode; |
|---|
| 3415 | + if (dev->hw_dev->is_unite) |
|---|
| 3416 | + info->act_width = in_crop->width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; |
|---|
| 3417 | + else |
|---|
| 3418 | + info->act_width = in_crop->width; |
|---|
| 3419 | + info->act_height = in_crop->height; |
|---|
| 3420 | + return 0; |
|---|
| 3421 | +} |
|---|
| 3422 | + |
|---|
| 2502 | 3423 | static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) |
|---|
| 2503 | 3424 | { |
|---|
| 2504 | 3425 | struct rkisp_device *isp_dev = sd_to_isp_dev(sd); |
|---|
| 2505 | 3426 | struct rkisp_thunderboot_resmem *resmem; |
|---|
| 3427 | + struct rkisp32_thunderboot_resmem_head *tb_head_v32; |
|---|
| 2506 | 3428 | struct rkisp_thunderboot_resmem_head *head; |
|---|
| 2507 | 3429 | struct rkisp_thunderboot_shmem *shmem; |
|---|
| 2508 | 3430 | struct isp2x_buf_idxfd *idxfd; |
|---|
| 3431 | + struct rkisp_rx_buf *dbufs; |
|---|
| 2509 | 3432 | void *resmem_va; |
|---|
| 2510 | 3433 | long ret = 0; |
|---|
| 2511 | 3434 | |
|---|
| 2512 | | - if (!arg && cmd != RKISP_CMD_FREE_SHARED_BUF) |
|---|
| 3435 | + if (!arg && |
|---|
| 3436 | + (cmd != RKISP_CMD_FREE_SHARED_BUF && |
|---|
| 3437 | + cmd != RKISP_CMD_MULTI_DEV_FORCE_ENUM)) |
|---|
| 2513 | 3438 | return -EINVAL; |
|---|
| 2514 | 3439 | |
|---|
| 2515 | 3440 | switch (cmd) { |
|---|
| 2516 | 3441 | case RKISP_CMD_TRIGGER_READ_BACK: |
|---|
| 2517 | 3442 | rkisp_rdbk_trigger_event(isp_dev, T_CMD_QUEUE, arg); |
|---|
| 2518 | 3443 | break; |
|---|
| 3444 | + case RKISP_CMD_GET_ISP_INFO: |
|---|
| 3445 | + rkisp_get_info(isp_dev, arg); |
|---|
| 3446 | + break; |
|---|
| 3447 | + case RKISP_CMD_GET_TB_HEAD_V32: |
|---|
| 3448 | + if (isp_dev->tb_head.complete != RKISP_TB_OK || !isp_dev->is_pre_on) { |
|---|
| 3449 | + ret = -EINVAL; |
|---|
| 3450 | + break; |
|---|
| 3451 | + } |
|---|
| 3452 | + tb_head_v32 = arg; |
|---|
| 3453 | + memcpy(tb_head_v32, &isp_dev->tb_head, |
|---|
| 3454 | + sizeof(struct rkisp_thunderboot_resmem_head)); |
|---|
| 3455 | + memcpy(&tb_head_v32->cfg, isp_dev->params_vdev.isp32_params, |
|---|
| 3456 | + sizeof(struct isp32_isp_params_cfg)); |
|---|
| 3457 | + break; |
|---|
| 2519 | 3458 | case RKISP_CMD_GET_SHARED_BUF: |
|---|
| 3459 | + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { |
|---|
| 3460 | + ret = -ENOIOCTLCMD; |
|---|
| 3461 | + break; |
|---|
| 3462 | + } |
|---|
| 2520 | 3463 | resmem = (struct rkisp_thunderboot_resmem *)arg; |
|---|
| 2521 | 3464 | resmem->resmem_padr = isp_dev->resmem_pa; |
|---|
| 2522 | 3465 | resmem->resmem_size = isp_dev->resmem_size; |
|---|
| .. | .. |
|---|
| 2546 | 3489 | } |
|---|
| 2547 | 3490 | break; |
|---|
| 2548 | 3491 | case RKISP_CMD_FREE_SHARED_BUF: |
|---|
| 3492 | + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { |
|---|
| 3493 | + ret = -ENOIOCTLCMD; |
|---|
| 3494 | + break; |
|---|
| 3495 | + } |
|---|
| 2549 | 3496 | if (isp_dev->resmem_pa && isp_dev->resmem_size) { |
|---|
| 2550 | 3497 | dma_unmap_single(isp_dev->dev, isp_dev->resmem_pa, |
|---|
| 2551 | 3498 | sizeof(struct rkisp_thunderboot_resmem_head), |
|---|
| .. | .. |
|---|
| 2564 | 3511 | break; |
|---|
| 2565 | 3512 | case RKISP_CMD_SET_LDCHBUF_SIZE: |
|---|
| 2566 | 3513 | case RKISP_CMD_SET_MESHBUF_SIZE: |
|---|
| 2567 | | - rkisp_params_set_meshbuf_size(&isp_dev->params_vdev, arg); |
|---|
| 3514 | + ret = rkisp_params_set_meshbuf_size(&isp_dev->params_vdev, arg); |
|---|
| 2568 | 3515 | break; |
|---|
| 2569 | 3516 | case RKISP_CMD_GET_SHM_BUFFD: |
|---|
| 3517 | + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { |
|---|
| 3518 | + ret = -ENOIOCTLCMD; |
|---|
| 3519 | + break; |
|---|
| 3520 | + } |
|---|
| 2570 | 3521 | shmem = (struct rkisp_thunderboot_shmem *)arg; |
|---|
| 2571 | 3522 | ret = rkisp_tb_shm_ioctl(shmem); |
|---|
| 2572 | 3523 | break; |
|---|
| 2573 | 3524 | case RKISP_CMD_GET_FBCBUF_FD: |
|---|
| 2574 | 3525 | idxfd = (struct isp2x_buf_idxfd *)arg; |
|---|
| 2575 | 3526 | ret = rkisp_bridge_get_fbcbuf_fd(isp_dev, idxfd); |
|---|
| 3527 | + break; |
|---|
| 3528 | + case RKISP_CMD_INFO2DDR: |
|---|
| 3529 | + ret = rkisp_params_info2ddr_cfg(&isp_dev->params_vdev, arg); |
|---|
| 3530 | + break; |
|---|
| 3531 | + case RKISP_CMD_MESHBUF_FREE: |
|---|
| 3532 | + rkisp_params_meshbuf_free(&isp_dev->params_vdev, *(u64 *)arg); |
|---|
| 3533 | + break; |
|---|
| 3534 | + case RKISP_VICAP_CMD_RX_BUFFER_FREE: |
|---|
| 3535 | + dbufs = (struct rkisp_rx_buf *)arg; |
|---|
| 3536 | + rkisp_rx_buf_free(isp_dev, dbufs); |
|---|
| 3537 | + break; |
|---|
| 3538 | + case RKISP_CMD_MULTI_DEV_FORCE_ENUM: |
|---|
| 3539 | + if (isp_dev->hw_dev->is_runing) { |
|---|
| 3540 | + ret = -EINVAL; |
|---|
| 3541 | + } else { |
|---|
| 3542 | + isp_dev->hw_dev->is_single = true; |
|---|
| 3543 | + isp_dev->hw_dev->is_multi_overflow = false; |
|---|
| 3544 | + rkisp_hw_enum_isp_size(isp_dev->hw_dev); |
|---|
| 3545 | + } |
|---|
| 2576 | 3546 | break; |
|---|
| 2577 | 3547 | default: |
|---|
| 2578 | 3548 | ret = -ENOIOCTLCMD; |
|---|
| .. | .. |
|---|
| 2594 | 3564 | struct rkisp_meshbuf_size meshsize; |
|---|
| 2595 | 3565 | struct rkisp_thunderboot_shmem shmem; |
|---|
| 2596 | 3566 | struct isp2x_buf_idxfd idxfd; |
|---|
| 3567 | + struct rkisp_info2ddr info2ddr; |
|---|
| 2597 | 3568 | long ret = 0; |
|---|
| 3569 | + u64 module_id; |
|---|
| 2598 | 3570 | |
|---|
| 2599 | 3571 | if (!up && cmd != RKISP_CMD_FREE_SHARED_BUF) |
|---|
| 2600 | 3572 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 2606 | 3578 | ret = rkisp_ioctl(sd, cmd, &trigger); |
|---|
| 2607 | 3579 | break; |
|---|
| 2608 | 3580 | case RKISP_CMD_GET_SHARED_BUF: |
|---|
| 3581 | + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { |
|---|
| 3582 | + ret = -ENOIOCTLCMD; |
|---|
| 3583 | + break; |
|---|
| 3584 | + } |
|---|
| 2609 | 3585 | ret = rkisp_ioctl(sd, cmd, &resmem); |
|---|
| 2610 | 3586 | if (!ret && copy_to_user(up, &resmem, sizeof(resmem))) |
|---|
| 2611 | 3587 | ret = -EFAULT; |
|---|
| 2612 | 3588 | break; |
|---|
| 2613 | 3589 | case RKISP_CMD_FREE_SHARED_BUF: |
|---|
| 3590 | + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { |
|---|
| 3591 | + ret = -ENOIOCTLCMD; |
|---|
| 3592 | + break; |
|---|
| 3593 | + } |
|---|
| 2614 | 3594 | ret = rkisp_ioctl(sd, cmd, NULL); |
|---|
| 2615 | 3595 | break; |
|---|
| 2616 | 3596 | case RKISP_CMD_GET_LDCHBUF_INFO: |
|---|
| .. | .. |
|---|
| 2624 | 3604 | ret = rkisp_ioctl(sd, cmd, &ldchsize); |
|---|
| 2625 | 3605 | break; |
|---|
| 2626 | 3606 | case RKISP_CMD_GET_MESHBUF_INFO: |
|---|
| 2627 | | - if (copy_from_user(&meshsize, up, sizeof(meshsize))) |
|---|
| 3607 | + if (copy_from_user(&meshbuf, up, sizeof(meshbuf))) |
|---|
| 2628 | 3608 | return -EFAULT; |
|---|
| 2629 | 3609 | ret = rkisp_ioctl(sd, cmd, &meshbuf); |
|---|
| 2630 | 3610 | if (!ret && copy_to_user(up, &meshbuf, sizeof(meshbuf))) |
|---|
| .. | .. |
|---|
| 2636 | 3616 | ret = rkisp_ioctl(sd, cmd, &meshsize); |
|---|
| 2637 | 3617 | break; |
|---|
| 2638 | 3618 | case RKISP_CMD_GET_SHM_BUFFD: |
|---|
| 3619 | + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { |
|---|
| 3620 | + ret = -ENOIOCTLCMD; |
|---|
| 3621 | + break; |
|---|
| 3622 | + } |
|---|
| 2639 | 3623 | if (copy_from_user(&shmem, up, sizeof(shmem))) |
|---|
| 2640 | 3624 | return -EFAULT; |
|---|
| 2641 | 3625 | ret = rkisp_ioctl(sd, cmd, &shmem); |
|---|
| .. | .. |
|---|
| 2646 | 3630 | ret = rkisp_ioctl(sd, cmd, &idxfd); |
|---|
| 2647 | 3631 | if (!ret && copy_to_user(up, &idxfd, sizeof(idxfd))) |
|---|
| 2648 | 3632 | ret = -EFAULT; |
|---|
| 3633 | + break; |
|---|
| 3634 | + case RKISP_CMD_INFO2DDR: |
|---|
| 3635 | + if (copy_from_user(&info2ddr, up, sizeof(info2ddr))) |
|---|
| 3636 | + return -EFAULT; |
|---|
| 3637 | + ret = rkisp_ioctl(sd, cmd, &info2ddr); |
|---|
| 3638 | + if (!ret && copy_to_user(up, &info2ddr, sizeof(info2ddr))) |
|---|
| 3639 | + ret = -EFAULT; |
|---|
| 3640 | + break; |
|---|
| 3641 | + case RKISP_CMD_MESHBUF_FREE: |
|---|
| 3642 | + if (copy_from_user(&module_id, up, sizeof(module_id))) |
|---|
| 3643 | + return -EFAULT; |
|---|
| 3644 | + ret = rkisp_ioctl(sd, cmd, &module_id); |
|---|
| 3645 | + break; |
|---|
| 3646 | + case RKISP_CMD_MULTI_DEV_FORCE_ENUM: |
|---|
| 3647 | + ret = rkisp_ioctl(sd, cmd, NULL); |
|---|
| 2649 | 3648 | break; |
|---|
| 2650 | 3649 | default: |
|---|
| 2651 | 3650 | ret = -ENOIOCTLCMD; |
|---|
| .. | .. |
|---|
| 2673 | 3672 | |
|---|
| 2674 | 3673 | static const struct v4l2_subdev_video_ops rkisp_isp_sd_video_ops = { |
|---|
| 2675 | 3674 | .s_stream = rkisp_isp_sd_s_stream, |
|---|
| 3675 | + .s_rx_buffer = rkisp_sd_s_rx_buffer, |
|---|
| 2676 | 3676 | }; |
|---|
| 2677 | 3677 | |
|---|
| 2678 | 3678 | static const struct v4l2_subdev_core_ops rkisp_isp_core_ops = { |
|---|
| .. | .. |
|---|
| 2723 | 3723 | struct v4l2_subdev *sd = &isp_sdev->sd; |
|---|
| 2724 | 3724 | int ret; |
|---|
| 2725 | 3725 | |
|---|
| 3726 | + mutex_init(&isp_dev->buf_lock); |
|---|
| 3727 | + spin_lock_init(&isp_dev->cmsk_lock); |
|---|
| 2726 | 3728 | spin_lock_init(&isp_dev->rdbk_lock); |
|---|
| 2727 | 3729 | ret = kfifo_alloc(&isp_dev->rdbk_kfifo, |
|---|
| 2728 | 3730 | 16 * sizeof(struct isp2x_csi_trigger), GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 2760 | 3762 | rkisp_isp_sd_init_default_fmt(isp_sdev); |
|---|
| 2761 | 3763 | isp_dev->hdr.sensor = NULL; |
|---|
| 2762 | 3764 | isp_dev->isp_state = ISP_STOP; |
|---|
| 2763 | | - |
|---|
| 3765 | + atomic_set(&isp_sdev->frm_sync_seq, 0); |
|---|
| 2764 | 3766 | rkisp_monitor_init(isp_dev); |
|---|
| 3767 | + INIT_WORK(&isp_dev->rdbk_work, rkisp_rdbk_work); |
|---|
| 2765 | 3768 | return 0; |
|---|
| 2766 | 3769 | err_cleanup_media_entity: |
|---|
| 2767 | 3770 | media_entity_cleanup(&sd->entity); |
|---|
| .. | .. |
|---|
| 2804 | 3807 | #ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP |
|---|
| 2805 | 3808 | void rkisp_chk_tb_over(struct rkisp_device *isp_dev) |
|---|
| 2806 | 3809 | { |
|---|
| 3810 | + struct rkisp_hw_dev *hw = isp_dev->hw_dev; |
|---|
| 2807 | 3811 | struct rkisp_thunderboot_resmem_head *head; |
|---|
| 2808 | 3812 | enum rkisp_tb_state tb_state; |
|---|
| 2809 | 3813 | void *resmem_va; |
|---|
| 2810 | 3814 | |
|---|
| 2811 | | - if (!isp_dev->hw_dev->is_thunderboot) |
|---|
| 3815 | + if (!isp_dev->is_thunderboot) |
|---|
| 2812 | 3816 | return; |
|---|
| 2813 | | - |
|---|
| 2814 | | - if (!atomic_read(&isp_dev->hw_dev->tb_ref)) { |
|---|
| 2815 | | - rkisp_tb_set_state(RKISP_TB_NG); |
|---|
| 2816 | | - rkisp_tb_unprotect_clk(); |
|---|
| 2817 | | - rkisp_register_irq(isp_dev->hw_dev); |
|---|
| 2818 | | - isp_dev->hw_dev->is_thunderboot = false; |
|---|
| 2819 | | - return; |
|---|
| 2820 | | - } |
|---|
| 2821 | 3817 | |
|---|
| 2822 | 3818 | resmem_va = phys_to_virt(isp_dev->resmem_pa); |
|---|
| 2823 | 3819 | head = (struct rkisp_thunderboot_resmem_head *)resmem_va; |
|---|
| 2824 | | - if (isp_dev->is_thunderboot) { |
|---|
| 2825 | | - shm_head_poll_timeout(isp_dev, !!head->enable, 2000, 200 * USEC_PER_MSEC); |
|---|
| 2826 | | - shm_head_poll_timeout(isp_dev, !!head->complete, 5000, 600 * USEC_PER_MSEC); |
|---|
| 2827 | | - if (head->complete != RKISP_TB_OK) |
|---|
| 2828 | | - v4l2_info(&isp_dev->v4l2_dev, |
|---|
| 2829 | | - "wait thunderboot over timeout\n"); |
|---|
| 3820 | + dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr, |
|---|
| 3821 | + sizeof(struct rkisp_thunderboot_resmem_head), |
|---|
| 3822 | + DMA_FROM_DEVICE); |
|---|
| 2830 | 3823 | |
|---|
| 2831 | | - v4l2_info(&isp_dev->v4l2_dev, |
|---|
| 2832 | | - "thunderboot info: %d, %d, %d, %d, %d, %d, 0x%x\n", |
|---|
| 2833 | | - head->enable, |
|---|
| 2834 | | - head->complete, |
|---|
| 2835 | | - head->frm_total, |
|---|
| 2836 | | - head->hdr_mode, |
|---|
| 2837 | | - head->width, |
|---|
| 2838 | | - head->height, |
|---|
| 2839 | | - head->bus_fmt); |
|---|
| 3824 | + shm_head_poll_timeout(isp_dev, !!head->complete, 5000, 200 * USEC_PER_MSEC); |
|---|
| 3825 | + if (head->complete != RKISP_TB_OK) { |
|---|
| 3826 | + v4l2_err(&isp_dev->v4l2_dev, "wait thunderboot over timeout\n"); |
|---|
| 3827 | + } else { |
|---|
| 3828 | + struct rkisp_isp_params_vdev *params_vdev = &isp_dev->params_vdev; |
|---|
| 3829 | + void *param = NULL; |
|---|
| 3830 | + u32 size = 0, offset = 0, timeout = 50; |
|---|
| 2840 | 3831 | |
|---|
| 2841 | | - tb_state = RKISP_TB_OK; |
|---|
| 2842 | | - if (head->complete != RKISP_TB_OK) { |
|---|
| 2843 | | - head->frm_total = 0; |
|---|
| 2844 | | - tb_state = RKISP_TB_NG; |
|---|
| 3832 | + /* wait for all isp dev to register */ |
|---|
| 3833 | + if (head->camera_num > 1) { |
|---|
| 3834 | + while (timeout--) { |
|---|
| 3835 | + if (hw->dev_num >= head->camera_num && |
|---|
| 3836 | + hw->isp[hw->dev_num - 1]->is_probe_end) |
|---|
| 3837 | + break; |
|---|
| 3838 | + usleep_range(200, 210); |
|---|
| 3839 | + } |
|---|
| 2845 | 3840 | } |
|---|
| 3841 | + |
|---|
| 3842 | + switch (isp_dev->isp_ver) { |
|---|
| 3843 | + case ISP_V32: |
|---|
| 3844 | + size = sizeof(struct rkisp32_thunderboot_resmem_head); |
|---|
| 3845 | + offset = size * isp_dev->dev_id; |
|---|
| 3846 | + break; |
|---|
| 3847 | + default: |
|---|
| 3848 | + break; |
|---|
| 3849 | + } |
|---|
| 3850 | + |
|---|
| 3851 | + if (size && size < isp_dev->resmem_size) { |
|---|
| 3852 | + dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr + offset, |
|---|
| 3853 | + size, DMA_FROM_DEVICE); |
|---|
| 3854 | + params_vdev->is_first_cfg = true; |
|---|
| 3855 | + if (isp_dev->isp_ver == ISP_V32) { |
|---|
| 3856 | + struct rkisp32_thunderboot_resmem_head *tmp = resmem_va + offset; |
|---|
| 3857 | + |
|---|
| 3858 | + param = &tmp->cfg; |
|---|
| 3859 | + head = &tmp->head; |
|---|
| 3860 | + v4l2_info(&isp_dev->v4l2_dev, |
|---|
| 3861 | + "tb param module en:0x%llx upd:0x%llx cfg upd:0x%llx\n", |
|---|
| 3862 | + tmp->cfg.module_en_update, |
|---|
| 3863 | + tmp->cfg.module_ens, |
|---|
| 3864 | + tmp->cfg.module_cfg_update); |
|---|
| 3865 | + } |
|---|
| 3866 | + if (param) |
|---|
| 3867 | + params_vdev->ops->save_first_param(params_vdev, param); |
|---|
| 3868 | + } else if (size > isp_dev->resmem_size) { |
|---|
| 3869 | + v4l2_err(&isp_dev->v4l2_dev, |
|---|
| 3870 | + "resmem size:%zu no enough for head:%d\n", |
|---|
| 3871 | + isp_dev->resmem_size, size); |
|---|
| 3872 | + head->complete = RKISP_TB_NG; |
|---|
| 3873 | + } |
|---|
| 3874 | + } |
|---|
| 3875 | + memcpy(&isp_dev->tb_head, head, sizeof(*head)); |
|---|
| 3876 | + v4l2_info(&isp_dev->v4l2_dev, |
|---|
| 3877 | + "thunderboot info: %d, %d, %d, %d, %d, %d | %d %d\n", |
|---|
| 3878 | + head->enable, |
|---|
| 3879 | + head->complete, |
|---|
| 3880 | + head->frm_total, |
|---|
| 3881 | + head->hdr_mode, |
|---|
| 3882 | + head->width, |
|---|
| 3883 | + head->height, |
|---|
| 3884 | + head->camera_num, |
|---|
| 3885 | + head->camera_index); |
|---|
| 3886 | + |
|---|
| 3887 | + tb_state = RKISP_TB_OK; |
|---|
| 3888 | + if (head->complete != RKISP_TB_OK) { |
|---|
| 3889 | + head->frm_total = 0; |
|---|
| 3890 | + tb_state = RKISP_TB_NG; |
|---|
| 3891 | + } |
|---|
| 3892 | + |
|---|
| 3893 | + if (hw->is_thunderboot) { |
|---|
| 3894 | + rkisp_register_irq(hw); |
|---|
| 2846 | 3895 | rkisp_tb_set_state(tb_state); |
|---|
| 2847 | 3896 | rkisp_tb_unprotect_clk(); |
|---|
| 2848 | | - rkisp_register_irq(isp_dev->hw_dev); |
|---|
| 2849 | | - pm_runtime_put(isp_dev->hw_dev->dev); |
|---|
| 2850 | | - isp_dev->hw_dev->is_thunderboot = false; |
|---|
| 2851 | | - isp_dev->is_thunderboot = false; |
|---|
| 2852 | | - atomic_dec(&isp_dev->hw_dev->tb_ref); |
|---|
| 3897 | + hw->is_thunderboot = false; |
|---|
| 2853 | 3898 | } |
|---|
| 3899 | + isp_dev->is_thunderboot = false; |
|---|
| 2854 | 3900 | } |
|---|
| 2855 | 3901 | #endif |
|---|
| 2856 | 3902 | |
|---|
| .. | .. |
|---|
| 2958 | 4004 | unsigned int isp3a_mis, |
|---|
| 2959 | 4005 | struct rkisp_device *dev) |
|---|
| 2960 | 4006 | { |
|---|
| 2961 | | - void __iomem *base = dev->base_addr; |
|---|
| 4007 | + struct rkisp_hw_dev *hw = dev->hw_dev; |
|---|
| 4008 | + void __iomem *base = !hw->is_unite ? |
|---|
| 4009 | + hw->base_addr : hw->base_next_addr; |
|---|
| 2962 | 4010 | unsigned int isp_mis_tmp = 0; |
|---|
| 2963 | 4011 | unsigned int isp_err = 0; |
|---|
| 2964 | 4012 | u32 si3a_isr_mask = ISP2X_SIAWB_DONE | ISP2X_SIAF_FIN | |
|---|
| .. | .. |
|---|
| 2968 | 4016 | ISP2X_3A_RAWHIST_BIG | ISP2X_3A_RAWHIST_CH0 | |
|---|
| 2969 | 4017 | ISP2X_3A_RAWHIST_CH1 | ISP2X_3A_RAWHIST_CH2 | |
|---|
| 2970 | 4018 | ISP2X_3A_RAWAF_SUM | ISP2X_3A_RAWAF_LUM | |
|---|
| 2971 | | - ISP2X_3A_RAWAF | ISP2X_3A_RAWAWB; |
|---|
| 4019 | + ISP2X_3A_RAWAWB; |
|---|
| 2972 | 4020 | bool sof_event_later = false; |
|---|
| 2973 | 4021 | |
|---|
| 2974 | 4022 | /* |
|---|
| .. | .. |
|---|
| 2978 | 4026 | if (isp3a_mis & ISP2X_3A_RAWAE_BIG && dev->params_vdev.rdbk_times > 0) |
|---|
| 2979 | 4027 | writel(BIT(31), base + RAWAE_BIG1_BASE + RAWAE_BIG_CTRL); |
|---|
| 2980 | 4028 | |
|---|
| 4029 | + if (hw->is_unite) { |
|---|
| 4030 | + u32 val = rkisp_read(dev, ISP3X_ISP_RIS, true); |
|---|
| 4031 | + |
|---|
| 4032 | + if (val) { |
|---|
| 4033 | + rkisp_write(dev, ISP3X_ISP_ICR, val, true); |
|---|
| 4034 | + v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev, |
|---|
| 4035 | + "left isp isr:0x%x\n", val); |
|---|
| 4036 | + if (isp_mis & CIF_ISP_FRAME && !(val & CIF_ISP_FRAME)) { |
|---|
| 4037 | + /* wait isp0 frame end */ |
|---|
| 4038 | + int timeout = read_poll_timeout_atomic(rkisp_read, |
|---|
| 4039 | + val, val & CIF_ISP_FRAME, 20, 20 * 50, true, dev, ISP3X_ISP_RIS, true); |
|---|
| 4040 | + |
|---|
| 4041 | + if (val) |
|---|
| 4042 | + rkisp_write(dev, ISP3X_ISP_ICR, val, true); |
|---|
| 4043 | + if (timeout) |
|---|
| 4044 | + dev_err(dev->dev, "wait isp end timeout\n"); |
|---|
| 4045 | + } |
|---|
| 4046 | + } |
|---|
| 4047 | + } |
|---|
| 2981 | 4048 | v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev, |
|---|
| 2982 | 4049 | "isp isr:0x%x, 0x%x\n", isp_mis, isp3a_mis); |
|---|
| 2983 | 4050 | dev->isp_isr_cnt++; |
|---|
| 2984 | 4051 | /* start edge of v_sync */ |
|---|
| 2985 | 4052 | if (isp_mis & CIF_ISP_V_START) { |
|---|
| 2986 | | - if (dev->isp_state & ISP_FRAME_END) { |
|---|
| 2987 | | - u64 tmp = dev->isp_sdev.dbg.interval + |
|---|
| 2988 | | - dev->isp_sdev.dbg.timestamp; |
|---|
| 2989 | | - |
|---|
| 2990 | | - dev->isp_sdev.dbg.timestamp = ktime_get_ns(); |
|---|
| 2991 | | - /* v-blank: frame_end - frame_start */ |
|---|
| 2992 | | - dev->isp_sdev.dbg.delay = dev->isp_sdev.dbg.timestamp - tmp; |
|---|
| 2993 | | - } |
|---|
| 2994 | | - rkisp_set_state(&dev->isp_state, ISP_FRAME_VS); |
|---|
| 2995 | 4053 | if (dev->hw_dev->monitor.is_en) { |
|---|
| 2996 | 4054 | rkisp_set_state(&dev->hw_dev->monitor.state, ISP_FRAME_VS); |
|---|
| 2997 | 4055 | if (!completion_done(&dev->hw_dev->monitor.cmpl)) |
|---|
| 2998 | 4056 | complete(&dev->hw_dev->monitor.cmpl); |
|---|
| 2999 | 4057 | } |
|---|
| 3000 | | - /* last vsync to config next buf */ |
|---|
| 3001 | | - if (!dev->filt_state[RDBK_F_VS]) |
|---|
| 3002 | | - rkisp_bridge_update_mi(dev, isp_mis); |
|---|
| 3003 | | - else |
|---|
| 3004 | | - dev->filt_state[RDBK_F_VS]--; |
|---|
| 4058 | + |
|---|
| 3005 | 4059 | if (IS_HDR_RDBK(dev->hdr.op_mode)) { |
|---|
| 3006 | 4060 | /* read 3d lut at isp readback */ |
|---|
| 3007 | 4061 | if (!dev->hw_dev->is_single) |
|---|
| .. | .. |
|---|
| 3011 | 4065 | } |
|---|
| 3012 | 4066 | if (dev->cap_dev.stream[RKISP_STREAM_SP].interlaced) { |
|---|
| 3013 | 4067 | /* 0 = ODD 1 = EVEN */ |
|---|
| 3014 | | - if (dev->active_sensor->mbus.type == V4L2_MBUS_CSI2) { |
|---|
| 4068 | + if (dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) { |
|---|
| 3015 | 4069 | void __iomem *addr = NULL; |
|---|
| 3016 | 4070 | |
|---|
| 3017 | 4071 | if (dev->isp_ver == ISP_V10 || |
|---|
| .. | .. |
|---|
| 3035 | 4089 | if (dev->vs_irq < 0 && !sof_event_later) { |
|---|
| 3036 | 4090 | dev->isp_sdev.frm_timestamp = ktime_get_ns(); |
|---|
| 3037 | 4091 | rkisp_isp_queue_event_sof(&dev->isp_sdev); |
|---|
| 4092 | + rkisp_stream_frame_start(dev, isp_mis); |
|---|
| 3038 | 4093 | } |
|---|
| 3039 | 4094 | vs_skip: |
|---|
| 3040 | 4095 | writel(CIF_ISP_V_START, base + CIF_ISP_ICR); |
|---|
| .. | .. |
|---|
| 3078 | 4133 | } |
|---|
| 3079 | 4134 | } |
|---|
| 3080 | 4135 | |
|---|
| 4136 | + if (isp3a_mis & ISP2X_3A_RAWAF) { |
|---|
| 4137 | + writel(ISP3X_3A_RAWAF, base + ISP3X_ISP_3A_ICR); |
|---|
| 4138 | + /* 3a irq will with lsc_lut_err irq if isp version below isp32 */ |
|---|
| 4139 | + if (isp_mis & ISP2X_LSC_LUT_ERR) |
|---|
| 4140 | + isp_mis &= ~ISP2X_LSC_LUT_ERR; |
|---|
| 4141 | + if (dev->rawaf_irq_cnt == 0) |
|---|
| 4142 | + rkisp_stream_buf_done_early(dev); |
|---|
| 4143 | + dev->rawaf_irq_cnt++; |
|---|
| 4144 | + } |
|---|
| 4145 | + |
|---|
| 3081 | 4146 | if (isp_mis & ISP2X_LSC_LUT_ERR) { |
|---|
| 3082 | 4147 | writel(ISP2X_LSC_LUT_ERR, base + CIF_ISP_ICR); |
|---|
| 3083 | 4148 | |
|---|
| .. | .. |
|---|
| 3089 | 4154 | |
|---|
| 3090 | 4155 | /* sampled input frame is complete */ |
|---|
| 3091 | 4156 | if (isp_mis & CIF_ISP_FRAME_IN) { |
|---|
| 4157 | + dev->isp_sdev.dbg.interval = |
|---|
| 4158 | + ktime_get_ns() - dev->isp_sdev.dbg.timestamp; |
|---|
| 3092 | 4159 | rkisp_set_state(&dev->isp_state, ISP_FRAME_IN); |
|---|
| 3093 | 4160 | writel(CIF_ISP_FRAME_IN, base + CIF_ISP_ICR); |
|---|
| 3094 | 4161 | isp_mis_tmp = readl(base + CIF_ISP_MIS); |
|---|
| 3095 | 4162 | if (isp_mis_tmp & CIF_ISP_FRAME_IN) |
|---|
| 3096 | 4163 | v4l2_err(&dev->v4l2_dev, "isp icr frame_in err: 0x%x\n", |
|---|
| 3097 | 4164 | isp_mis_tmp); |
|---|
| 3098 | | - |
|---|
| 3099 | | - dev->isp_err_cnt = 0; |
|---|
| 3100 | | - dev->isp_state &= ~ISP_ERROR; |
|---|
| 3101 | 4165 | } |
|---|
| 3102 | 4166 | |
|---|
| 3103 | 4167 | /* frame was completely put out */ |
|---|
| 3104 | 4168 | if (isp_mis & CIF_ISP_FRAME) { |
|---|
| 3105 | | - dev->isp_sdev.dbg.interval = |
|---|
| 3106 | | - ktime_get_ns() - dev->isp_sdev.dbg.timestamp; |
|---|
| 4169 | + dev->rawaf_irq_cnt = 0; |
|---|
| 4170 | + if (!dev->is_pre_on || !IS_HDR_RDBK(dev->rd_mode)) |
|---|
| 4171 | + dev->isp_sdev.dbg.interval = |
|---|
| 4172 | + ktime_get_ns() - dev->isp_sdev.dbg.timestamp; |
|---|
| 3107 | 4173 | /* Clear Frame In (ISP) */ |
|---|
| 3108 | 4174 | rkisp_set_state(&dev->isp_state, ISP_FRAME_END); |
|---|
| 3109 | 4175 | writel(CIF_ISP_FRAME, base + CIF_ISP_ICR); |
|---|
| .. | .. |
|---|
| 3113 | 4179 | "isp icr frame end err: 0x%x\n", isp_mis_tmp); |
|---|
| 3114 | 4180 | rkisp_dmarx_get_frame(dev, &dev->isp_sdev.dbg.id, NULL, NULL, true); |
|---|
| 3115 | 4181 | rkisp_isp_read_add_fifo_data(dev); |
|---|
| 4182 | + |
|---|
| 4183 | + dev->isp_err_cnt = 0; |
|---|
| 4184 | + dev->isp_state &= ~ISP_ERROR; |
|---|
| 4185 | + } |
|---|
| 4186 | + |
|---|
| 4187 | + if (isp_mis & CIF_ISP_V_START) { |
|---|
| 4188 | + if (dev->isp_state & ISP_FRAME_END) { |
|---|
| 4189 | + u64 tmp = dev->isp_sdev.dbg.interval + |
|---|
| 4190 | + dev->isp_sdev.dbg.timestamp; |
|---|
| 4191 | + |
|---|
| 4192 | + dev->isp_sdev.dbg.timestamp = ktime_get_ns(); |
|---|
| 4193 | + /* v-blank: frame(N)start - frame(N-1)end */ |
|---|
| 4194 | + dev->isp_sdev.dbg.delay = dev->isp_sdev.dbg.timestamp - tmp; |
|---|
| 4195 | + } |
|---|
| 4196 | + rkisp_set_state(&dev->isp_state, ISP_FRAME_VS); |
|---|
| 4197 | + if (dev->procfs.is_fs_wait) { |
|---|
| 4198 | + dev->procfs.is_fs_wait = false; |
|---|
| 4199 | + wake_up(&dev->procfs.fs_wait); |
|---|
| 4200 | + } |
|---|
| 3116 | 4201 | } |
|---|
| 3117 | 4202 | |
|---|
| 3118 | 4203 | if ((isp_mis & (CIF_ISP_FRAME | si3a_isr_mask)) || |
|---|
| .. | .. |
|---|
| 3129 | 4214 | |
|---|
| 3130 | 4215 | if ((isp_mis & CIF_ISP_FRAME) && dev->stats_vdev.rdbk_mode) |
|---|
| 3131 | 4216 | rkisp_stats_rdbk_enable(&dev->stats_vdev, false); |
|---|
| 4217 | + |
|---|
| 4218 | + if (!IS_HDR_RDBK(dev->hdr.op_mode)) |
|---|
| 4219 | + rkisp_config_cmsk(dev); |
|---|
| 4220 | + } |
|---|
| 4221 | + |
|---|
| 4222 | + if (isp_mis & CIF_ISP_FRAME) { |
|---|
| 4223 | + if (dev->hw_dev->isp_ver == ISP_V32) { |
|---|
| 4224 | + struct rkisp_stream *s = &dev->cap_dev.stream[RKISP_STREAM_LUMA]; |
|---|
| 4225 | + |
|---|
| 4226 | + s->ops->frame_end(s, FRAME_IRQ); |
|---|
| 4227 | + } |
|---|
| 4228 | + if (dev->procfs.is_fe_wait) { |
|---|
| 4229 | + dev->procfs.is_fe_wait = false; |
|---|
| 4230 | + wake_up(&dev->procfs.fe_wait); |
|---|
| 4231 | + } |
|---|
| 3132 | 4232 | } |
|---|
| 3133 | 4233 | |
|---|
| 3134 | 4234 | /* |
|---|
| .. | .. |
|---|
| 3136 | 4236 | * lot of register writes. Do those only one per frame. |
|---|
| 3137 | 4237 | * Do the updates in the order of the processing flow. |
|---|
| 3138 | 4238 | */ |
|---|
| 3139 | | - rkisp_params_isr(&dev->params_vdev, isp_mis); |
|---|
| 4239 | + if (isp_mis & (CIF_ISP_V_START | CIF_ISP_FRAME)) |
|---|
| 4240 | + rkisp_params_isr(&dev->params_vdev, isp_mis); |
|---|
| 3140 | 4241 | |
|---|
| 3141 | 4242 | /* cur frame end and next frame start irq togeter */ |
|---|
| 3142 | 4243 | if (dev->vs_irq < 0 && sof_event_later) { |
|---|
| 3143 | 4244 | dev->isp_sdev.frm_timestamp = ktime_get_ns(); |
|---|
| 3144 | 4245 | rkisp_isp_queue_event_sof(&dev->isp_sdev); |
|---|
| 4246 | + rkisp_stream_frame_start(dev, isp_mis); |
|---|
| 3145 | 4247 | } |
|---|
| 3146 | 4248 | |
|---|
| 3147 | | - if (isp_mis & CIF_ISP_FRAME_IN) |
|---|
| 3148 | | - rkisp_check_idle(dev, ISP_FRAME_IN); |
|---|
| 4249 | + if (isp_mis & ISP3X_OUT_FRM_QUARTER) { |
|---|
| 4250 | + writel(ISP3X_OUT_FRM_QUARTER, base + CIF_ISP_ICR); |
|---|
| 4251 | + rkisp_dvbm_event(dev, ISP3X_OUT_FRM_QUARTER); |
|---|
| 4252 | + } |
|---|
| 4253 | + if (isp_mis & ISP3X_OUT_FRM_HALF) { |
|---|
| 4254 | + writel(ISP3X_OUT_FRM_HALF, base + CIF_ISP_ICR); |
|---|
| 4255 | + rkisp_dvbm_event(dev, ISP3X_OUT_FRM_HALF); |
|---|
| 4256 | + rkisp_stream_buf_done_early(dev); |
|---|
| 4257 | + } |
|---|
| 4258 | + if (isp_mis & ISP3X_OUT_FRM_END) { |
|---|
| 4259 | + writel(ISP3X_OUT_FRM_END, base + CIF_ISP_ICR); |
|---|
| 4260 | + rkisp_dvbm_event(dev, ISP3X_OUT_FRM_END); |
|---|
| 4261 | + } |
|---|
| 4262 | + |
|---|
| 3149 | 4263 | if (isp_mis & CIF_ISP_FRAME) |
|---|
| 3150 | 4264 | rkisp_check_idle(dev, ISP_FRAME_END); |
|---|
| 3151 | 4265 | } |
|---|