| .. | .. |
|---|
| 35 | 35 | * rkisp_hw |
|---|
| 36 | 36 | */ |
|---|
| 37 | 37 | |
|---|
| 38 | +struct backup_reg { |
|---|
| 39 | + const u32 base; |
|---|
| 40 | + const u32 shd; |
|---|
| 41 | + u32 val; |
|---|
| 42 | +}; |
|---|
| 43 | + |
|---|
| 38 | 44 | struct isp_irqs_data { |
|---|
| 39 | 45 | const char *name; |
|---|
| 40 | 46 | irqreturn_t (*irq_hdl)(int irq, void *ctx); |
|---|
| .. | .. |
|---|
| 132 | 138 | for (i = 0; i < size; i++) { |
|---|
| 133 | 139 | flag = dev->sw_base_addr + reg[i] + RKISP_ISP_SW_REG_SIZE; |
|---|
| 134 | 140 | *flag = SW_REG_CACHE; |
|---|
| 135 | | - if (dev->hw_dev->is_unite) { |
|---|
| 141 | + if (dev->hw_dev->unite) { |
|---|
| 136 | 142 | flag += RKISP_ISP_SW_MAX_SIZE / 4; |
|---|
| 137 | 143 | *flag = SW_REG_CACHE; |
|---|
| 138 | 144 | } |
|---|
| .. | .. |
|---|
| 144 | 150 | struct device *dev = ctx; |
|---|
| 145 | 151 | struct rkisp_hw_dev *hw_dev = dev_get_drvdata(dev); |
|---|
| 146 | 152 | struct rkisp_device *isp = hw_dev->isp[hw_dev->mipi_dev_id]; |
|---|
| 147 | | - void __iomem *base = !hw_dev->is_unite ? |
|---|
| 153 | + void __iomem *base = hw_dev->unite != ISP_UNITE_TWO ? |
|---|
| 148 | 154 | hw_dev->base_addr : hw_dev->base_next_addr; |
|---|
| 149 | 155 | ktime_t t = 0; |
|---|
| 150 | 156 | s64 us; |
|---|
| .. | .. |
|---|
| 201 | 207 | struct device *dev = ctx; |
|---|
| 202 | 208 | struct rkisp_hw_dev *hw_dev = dev_get_drvdata(dev); |
|---|
| 203 | 209 | struct rkisp_device *isp = hw_dev->isp[hw_dev->cur_dev_id]; |
|---|
| 204 | | - void __iomem *base = !hw_dev->is_unite ? |
|---|
| 210 | + void __iomem *base = hw_dev->unite != ISP_UNITE_TWO ? |
|---|
| 205 | 211 | hw_dev->base_addr : hw_dev->base_next_addr; |
|---|
| 206 | 212 | u32 mis_val, tx_isr = MI_RAW0_WR_FRAME | MI_RAW1_WR_FRAME | |
|---|
| 207 | 213 | MI_RAW2_WR_FRAME | MI_RAW3_WR_FRAME; |
|---|
| .. | .. |
|---|
| 237 | 243 | struct device *dev = ctx; |
|---|
| 238 | 244 | struct rkisp_hw_dev *hw_dev = dev_get_drvdata(dev); |
|---|
| 239 | 245 | struct rkisp_device *isp = hw_dev->isp[hw_dev->cur_dev_id]; |
|---|
| 240 | | - void __iomem *base = !hw_dev->is_unite ? |
|---|
| 246 | + void __iomem *base = hw_dev->unite != ISP_UNITE_TWO ? |
|---|
| 241 | 247 | hw_dev->base_addr : hw_dev->base_next_addr; |
|---|
| 242 | 248 | unsigned int mis_val, mis_3a = 0; |
|---|
| 243 | 249 | ktime_t t = 0; |
|---|
| .. | .. |
|---|
| 348 | 354 | return 0; |
|---|
| 349 | 355 | } |
|---|
| 350 | 356 | |
|---|
| 357 | +void rkisp_hw_reg_save(struct rkisp_hw_dev *dev) |
|---|
| 358 | +{ |
|---|
| 359 | + void *buf = dev->sw_reg; |
|---|
| 360 | + |
|---|
| 361 | + memcpy_fromio(buf, dev->base_addr, RKISP_ISP_SW_REG_SIZE); |
|---|
| 362 | + if (dev->unite == ISP_UNITE_TWO) { |
|---|
| 363 | + buf += RKISP_ISP_SW_REG_SIZE; |
|---|
| 364 | + memcpy_fromio(buf, dev->base_next_addr, RKISP_ISP_SW_REG_SIZE); |
|---|
| 365 | + } |
|---|
| 366 | +} |
|---|
| 367 | + |
|---|
| 368 | +void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev) |
|---|
| 369 | +{ |
|---|
| 370 | + struct rkisp_device *isp = dev->isp[dev->cur_dev_id]; |
|---|
| 371 | + void __iomem *base = dev->base_addr; |
|---|
| 372 | + void *reg_buf = dev->sw_reg; |
|---|
| 373 | + u32 val, *reg, *reg1, i, j; |
|---|
| 374 | + u32 self_upd_reg[] = { |
|---|
| 375 | + ISP21_BAY3D_BASE, ISP21_DRC_BASE, ISP3X_BAY3D_CTRL, |
|---|
| 376 | + ISP_DHAZ_CTRL, ISP3X_3DLUT_BASE, ISP_RAWAE_LITE_BASE, |
|---|
| 377 | + RAWAE_BIG1_BASE, RAWAE_BIG2_BASE, RAWAE_BIG3_BASE, |
|---|
| 378 | + ISP_RAWHIST_LITE_BASE, ISP_RAWHIST_BIG1_BASE, |
|---|
| 379 | + ISP_RAWHIST_BIG2_BASE, ISP_RAWHIST_BIG3_BASE, |
|---|
| 380 | + ISP_RAWAF_BASE, ISP_RAWAWB_BASE, ISP_LDCH_BASE, |
|---|
| 381 | + ISP3X_CAC_BASE, |
|---|
| 382 | + }; |
|---|
| 383 | + struct backup_reg backup[] = { |
|---|
| 384 | + { |
|---|
| 385 | + .base = MI_MP_WR_Y_BASE, |
|---|
| 386 | + .shd = MI_MP_WR_Y_BASE_SHD, |
|---|
| 387 | + }, { |
|---|
| 388 | + .base = MI_MP_WR_CB_BASE, |
|---|
| 389 | + .shd = MI_MP_WR_CB_BASE_SHD, |
|---|
| 390 | + }, { |
|---|
| 391 | + .base = MI_MP_WR_CR_BASE, |
|---|
| 392 | + .shd = MI_MP_WR_CR_BASE_SHD, |
|---|
| 393 | + }, { |
|---|
| 394 | + .base = MI_SP_WR_Y_BASE, |
|---|
| 395 | + .shd = MI_SP_WR_Y_BASE_SHD, |
|---|
| 396 | + }, { |
|---|
| 397 | + .base = MI_SP_WR_CB_BASE, |
|---|
| 398 | + .shd = MI_SP_WR_CB_BASE_AD_SHD, |
|---|
| 399 | + }, { |
|---|
| 400 | + .base = MI_SP_WR_CR_BASE, |
|---|
| 401 | + .shd = MI_SP_WR_CR_BASE_AD_SHD, |
|---|
| 402 | + }, { |
|---|
| 403 | + .base = ISP3X_MI_BP_WR_Y_BASE, |
|---|
| 404 | + .shd = ISP3X_MI_BP_WR_Y_BASE_SHD, |
|---|
| 405 | + }, { |
|---|
| 406 | + .base = ISP3X_MI_BP_WR_CB_BASE, |
|---|
| 407 | + .shd = ISP3X_MI_BP_WR_CB_BASE_SHD, |
|---|
| 408 | + }, { |
|---|
| 409 | + .base = ISP32_MI_MPDS_WR_Y_BASE, |
|---|
| 410 | + .shd = ISP32_MI_MPDS_WR_Y_BASE_SHD, |
|---|
| 411 | + }, { |
|---|
| 412 | + .base = ISP32_MI_MPDS_WR_CB_BASE, |
|---|
| 413 | + .shd = ISP32_MI_MPDS_WR_CB_BASE_SHD, |
|---|
| 414 | + }, { |
|---|
| 415 | + .base = ISP32_MI_BPDS_WR_Y_BASE, |
|---|
| 416 | + .shd = ISP32_MI_BPDS_WR_Y_BASE_SHD, |
|---|
| 417 | + }, { |
|---|
| 418 | + .base = ISP32_MI_BPDS_WR_CB_BASE, |
|---|
| 419 | + .shd = ISP32_MI_BPDS_WR_CB_BASE_SHD, |
|---|
| 420 | + }, { |
|---|
| 421 | + .base = MI_RAW0_WR_BASE, |
|---|
| 422 | + .shd = MI_RAW0_WR_BASE_SHD, |
|---|
| 423 | + }, { |
|---|
| 424 | + .base = MI_RAW1_WR_BASE, |
|---|
| 425 | + .shd = MI_RAW1_WR_BASE_SHD, |
|---|
| 426 | + }, { |
|---|
| 427 | + .base = MI_RAW2_WR_BASE, |
|---|
| 428 | + .shd = MI_RAW2_WR_BASE_SHD, |
|---|
| 429 | + }, { |
|---|
| 430 | + .base = MI_RAW3_WR_BASE, |
|---|
| 431 | + .shd = MI_RAW3_WR_BASE_SHD, |
|---|
| 432 | + }, { |
|---|
| 433 | + .base = MI_RAW0_RD_BASE, |
|---|
| 434 | + .shd = MI_RAW0_RD_BASE_SHD, |
|---|
| 435 | + }, { |
|---|
| 436 | + .base = MI_RAW1_RD_BASE, |
|---|
| 437 | + .shd = MI_RAW1_RD_BASE_SHD, |
|---|
| 438 | + }, { |
|---|
| 439 | + .base = MI_RAW2_RD_BASE, |
|---|
| 440 | + .shd = MI_RAW2_RD_BASE_SHD, |
|---|
| 441 | + }, { |
|---|
| 442 | + .base = MI_GAIN_WR_BASE, |
|---|
| 443 | + .shd = MI_GAIN_WR_BASE_SHD, |
|---|
| 444 | + } |
|---|
| 445 | + }; |
|---|
| 446 | + |
|---|
| 447 | + for (i = 0; i <= !!dev->unite; i++) { |
|---|
| 448 | + if (dev->unite != ISP_UNITE_TWO && i) |
|---|
| 449 | + break; |
|---|
| 450 | + |
|---|
| 451 | + if (i) { |
|---|
| 452 | + reg_buf += RKISP_ISP_SW_REG_SIZE; |
|---|
| 453 | + base = dev->base_next_addr; |
|---|
| 454 | + } |
|---|
| 455 | + |
|---|
| 456 | + /* process special reg */ |
|---|
| 457 | + for (j = 0; j < ARRAY_SIZE(self_upd_reg); j++) { |
|---|
| 458 | + reg = reg_buf + self_upd_reg[j]; |
|---|
| 459 | + *reg &= ~ISP21_SELF_FORCE_UPD; |
|---|
| 460 | + if (self_upd_reg[j] == ISP3X_3DLUT_BASE && *reg & ISP_3DLUT_EN) { |
|---|
| 461 | + reg = reg_buf + ISP3X_3DLUT_UPDATE; |
|---|
| 462 | + *reg = 1; |
|---|
| 463 | + } |
|---|
| 464 | + } |
|---|
| 465 | + reg = reg_buf + ISP_CTRL; |
|---|
| 466 | + *reg &= ~(CIF_ISP_CTRL_ISP_ENABLE | |
|---|
| 467 | + CIF_ISP_CTRL_ISP_INFORM_ENABLE | |
|---|
| 468 | + CIF_ISP_CTRL_ISP_CFG_UPD); |
|---|
| 469 | + reg = reg_buf + MI_WR_INIT; |
|---|
| 470 | + *reg = 0; |
|---|
| 471 | + reg = reg_buf + CSI2RX_CTRL0; |
|---|
| 472 | + *reg &= ~SW_CSI2RX_EN; |
|---|
| 473 | + for (j = 0; j < RKISP_ISP_SW_REG_SIZE; j += 4) { |
|---|
| 474 | + /* skip table RAM */ |
|---|
| 475 | + if ((j > ISP3X_LSC_CTRL && j < ISP3X_LSC_XGRAD_01) || |
|---|
| 476 | + (j > ISP32_CAC_OFFSET && j < ISP3X_CAC_RO_CNT) || |
|---|
| 477 | + (j > ISP3X_3DLUT_UPDATE && j < ISP3X_GAIN_BASE) || |
|---|
| 478 | + (j == 0x4840 || j == 0x4a80 || j == 0x4b40 || j == 0x5660)) |
|---|
| 479 | + continue; |
|---|
| 480 | + /* skip mmu range */ |
|---|
| 481 | + if (dev->isp_ver < ISP_V30 && |
|---|
| 482 | + j > ISP21_MI_BAY3D_RD_BASE_SHD && j < CSI2RX_CTRL0) |
|---|
| 483 | + continue; |
|---|
| 484 | + /* reg value of read diff to write */ |
|---|
| 485 | + if (j == ISP_MPFBC_CTRL || |
|---|
| 486 | + j == ISP32_ISP_AWB1_GAIN_G || j == ISP32_ISP_AWB1_GAIN_RB) |
|---|
| 487 | + reg = isp->sw_base_addr + j; |
|---|
| 488 | + else |
|---|
| 489 | + reg = reg_buf + j; |
|---|
| 490 | + writel(*reg, base + j); |
|---|
| 491 | + } |
|---|
| 492 | + |
|---|
| 493 | + /* config shd_reg to base_reg */ |
|---|
| 494 | + for (j = 0; j < ARRAY_SIZE(backup); j++) { |
|---|
| 495 | + reg = reg_buf + backup[j].base; |
|---|
| 496 | + reg1 = reg_buf + backup[j].shd; |
|---|
| 497 | + backup[j].val = *reg; |
|---|
| 498 | + writel(*reg1, base + backup[j].base); |
|---|
| 499 | + } |
|---|
| 500 | + |
|---|
| 501 | + /* update module */ |
|---|
| 502 | + reg = reg_buf + DUAL_CROP_CTRL; |
|---|
| 503 | + if (*reg & 0xf) |
|---|
| 504 | + writel(*reg | CIF_DUAL_CROP_CFG_UPD, base + DUAL_CROP_CTRL); |
|---|
| 505 | + reg = reg_buf + SELF_RESIZE_CTRL; |
|---|
| 506 | + if (*reg & 0xf) { |
|---|
| 507 | + if (dev->isp_ver == ISP_V32_L) |
|---|
| 508 | + writel(*reg | ISP32_SCALE_FORCE_UPD, base + ISP32_SELF_SCALE_UPDATE); |
|---|
| 509 | + else |
|---|
| 510 | + writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + SELF_RESIZE_CTRL); |
|---|
| 511 | + } |
|---|
| 512 | + reg = reg_buf + MAIN_RESIZE_CTRL; |
|---|
| 513 | + if (*reg & 0xf) |
|---|
| 514 | + writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + MAIN_RESIZE_CTRL); |
|---|
| 515 | + reg = reg_buf + ISP32_BP_RESIZE_CTRL; |
|---|
| 516 | + if (*reg & 0xf) |
|---|
| 517 | + writel(*reg | CIF_RSZ_CTRL_CFG_UPD, base + ISP32_BP_RESIZE_CTRL); |
|---|
| 518 | + |
|---|
| 519 | + /* update mi and isp, base_reg will update to shd_reg */ |
|---|
| 520 | + writel(CIF_MI_INIT_SOFT_UPD, base + MI_WR_INIT); |
|---|
| 521 | + |
|---|
| 522 | + /* config base_reg */ |
|---|
| 523 | + for (j = 0; j < ARRAY_SIZE(backup); j++) |
|---|
| 524 | + writel(backup[j].val, base + backup[j].base); |
|---|
| 525 | + /* base_reg = shd_reg, write is base but read is shd */ |
|---|
| 526 | + val = rkisp_read_reg_cache(isp, ISP_MPFBC_HEAD_PTR); |
|---|
| 527 | + writel(val, base + ISP_MPFBC_HEAD_PTR); |
|---|
| 528 | + val = rkisp_read_reg_cache(isp, MI_SWS_3A_WR_BASE); |
|---|
| 529 | + writel(val, base + MI_SWS_3A_WR_BASE); |
|---|
| 530 | + } |
|---|
| 531 | + |
|---|
| 532 | + rkisp_params_cfgsram(&isp->params_vdev, false); |
|---|
| 533 | + |
|---|
| 534 | + reg = reg_buf + ISP_CTRL; |
|---|
| 535 | + *reg |= CIF_ISP_CTRL_ISP_ENABLE | |
|---|
| 536 | + CIF_ISP_CTRL_ISP_CFG_UPD | |
|---|
| 537 | + CIF_ISP_CTRL_ISP_INFORM_ENABLE; |
|---|
| 538 | + writel(*reg, dev->base_addr + ISP_CTRL); |
|---|
| 539 | + if (dev->unite == ISP_UNITE_TWO) |
|---|
| 540 | + writel(*reg, dev->base_next_addr + ISP_CTRL); |
|---|
| 541 | +} |
|---|
| 542 | + |
|---|
| 351 | 543 | static const char * const rk3562_isp_clks[] = { |
|---|
| 352 | 544 | "clk_isp_core", |
|---|
| 353 | 545 | "aclk_isp", |
|---|
| .. | .. |
|---|
| 455 | 647 | }, { |
|---|
| 456 | 648 | .clk_rate = 350, |
|---|
| 457 | 649 | .refer_data = 3072, |
|---|
| 650 | + }, { |
|---|
| 651 | + .clk_rate = 440, |
|---|
| 652 | + .refer_data = 3840, |
|---|
| 458 | 653 | } |
|---|
| 459 | 654 | }; |
|---|
| 460 | 655 | |
|---|
| .. | .. |
|---|
| 636 | 831 | /* record clk config and recover */ |
|---|
| 637 | 832 | iccl0 = readl(base + CIF_ICCL); |
|---|
| 638 | 833 | clk_ctrl0 = readl(base + CTRL_VI_ISP_CLK_CTRL); |
|---|
| 639 | | - if (dev->is_unite) { |
|---|
| 834 | + if (dev->unite == ISP_UNITE_TWO) { |
|---|
| 640 | 835 | iccl1 = readl(dev->base_next_addr + CIF_ICCL); |
|---|
| 641 | 836 | clk_ctrl1 = readl(dev->base_next_addr + CTRL_VI_ISP_CLK_CTRL); |
|---|
| 642 | 837 | } |
|---|
| .. | .. |
|---|
| 646 | 841 | * isp soft reset first to protect isp reset. |
|---|
| 647 | 842 | */ |
|---|
| 648 | 843 | writel(0xffff, base + CIF_IRCL); |
|---|
| 649 | | - if (dev->is_unite) |
|---|
| 844 | + if (dev->unite == ISP_UNITE_TWO) |
|---|
| 650 | 845 | writel(0xffff, dev->base_next_addr + CIF_IRCL); |
|---|
| 651 | 846 | udelay(10); |
|---|
| 652 | 847 | } |
|---|
| .. | .. |
|---|
| 669 | 864 | writel(val, base + CIF_IRCL); |
|---|
| 670 | 865 | if (dev->isp_ver == ISP_V32) |
|---|
| 671 | 866 | rv1106_sdmmc_put_lock(); |
|---|
| 672 | | - if (dev->is_unite) |
|---|
| 867 | + if (dev->unite == ISP_UNITE_TWO) |
|---|
| 673 | 868 | writel(0xffff, dev->base_next_addr + CIF_IRCL); |
|---|
| 674 | 869 | udelay(10); |
|---|
| 675 | 870 | |
|---|
| .. | .. |
|---|
| 681 | 876 | |
|---|
| 682 | 877 | writel(iccl0, base + CIF_ICCL); |
|---|
| 683 | 878 | writel(clk_ctrl0, base + CTRL_VI_ISP_CLK_CTRL); |
|---|
| 684 | | - if (dev->is_unite) { |
|---|
| 879 | + if (dev->unite == ISP_UNITE_TWO) { |
|---|
| 685 | 880 | writel(iccl1, dev->base_next_addr + CIF_ICCL); |
|---|
| 686 | 881 | writel(clk_ctrl1, dev->base_next_addr + CTRL_VI_ISP_CLK_CTRL); |
|---|
| 687 | 882 | } |
|---|
| .. | .. |
|---|
| 722 | 917 | writel(val, dev->base_addr + CIF_ICCL); |
|---|
| 723 | 918 | if (dev->isp_ver == ISP_V32) |
|---|
| 724 | 919 | rv1106_sdmmc_put_lock(); |
|---|
| 725 | | - if (dev->is_unite) |
|---|
| 920 | + if (dev->unite == ISP_UNITE_TWO) |
|---|
| 726 | 921 | writel(val, dev->base_next_addr + CIF_ICCL); |
|---|
| 727 | 922 | |
|---|
| 728 | 923 | if (dev->isp_ver == ISP_V12 || dev->isp_ver == ISP_V13) { |
|---|
| .. | .. |
|---|
| 752 | 947 | writel(val, dev->base_addr + CTRL_VI_ISP_CLK_CTRL); |
|---|
| 753 | 948 | if (dev->isp_ver == ISP_V32) |
|---|
| 754 | 949 | rv1106_sdmmc_put_lock(); |
|---|
| 755 | | - if (dev->is_unite) |
|---|
| 950 | + if (dev->unite == ISP_UNITE_TWO) |
|---|
| 756 | 951 | writel(val, dev->base_next_addr + CTRL_VI_ISP_CLK_CTRL); |
|---|
| 757 | 952 | } |
|---|
| 758 | 953 | } |
|---|
| .. | .. |
|---|
| 776 | 971 | static int enable_sys_clk(struct rkisp_hw_dev *dev) |
|---|
| 777 | 972 | { |
|---|
| 778 | 973 | int i, ret = -EINVAL; |
|---|
| 779 | | - unsigned long rate; |
|---|
| 780 | 974 | |
|---|
| 781 | 975 | for (i = 0; i < dev->num_clks; i++) { |
|---|
| 782 | 976 | if (!IS_ERR(dev->clks[i])) { |
|---|
| .. | .. |
|---|
| 786 | 980 | } |
|---|
| 787 | 981 | } |
|---|
| 788 | 982 | |
|---|
| 789 | | - rate = dev->clk_rate_tbl[0].clk_rate * 1000000UL; |
|---|
| 790 | | - rkisp_set_clk_rate(dev->clks[0], rate); |
|---|
| 791 | | - if (dev->is_unite) |
|---|
| 792 | | - rkisp_set_clk_rate(dev->clks[5], rate); |
|---|
| 793 | 983 | rkisp_soft_reset(dev, false); |
|---|
| 794 | 984 | isp_config_clk(dev, true); |
|---|
| 795 | 985 | return 0; |
|---|
| .. | .. |
|---|
| 846 | 1036 | struct device *dev = &pdev->dev; |
|---|
| 847 | 1037 | struct rkisp_hw_dev *hw_dev; |
|---|
| 848 | 1038 | struct resource *res; |
|---|
| 849 | | - int i, ret; |
|---|
| 1039 | + int i, ret, mult = 1; |
|---|
| 850 | 1040 | bool is_mem_reserved = true; |
|---|
| 1041 | + u32 clk_rate = 0; |
|---|
| 851 | 1042 | |
|---|
| 852 | 1043 | match = of_match_node(rkisp_hw_of_match, node); |
|---|
| 853 | 1044 | if (IS_ERR(match)) |
|---|
| 854 | 1045 | return PTR_ERR(match); |
|---|
| 1046 | + match_data = match->data; |
|---|
| 855 | 1047 | |
|---|
| 856 | 1048 | hw_dev = devm_kzalloc(dev, sizeof(*hw_dev), GFP_KERNEL); |
|---|
| 857 | 1049 | if (!hw_dev) |
|---|
| 858 | 1050 | return -ENOMEM; |
|---|
| 859 | 1051 | |
|---|
| 860 | | - match_data = match->data; |
|---|
| 861 | | - hw_dev->is_unite = match_data->unite; |
|---|
| 1052 | + if (match_data->unite) |
|---|
| 1053 | + mult = 2; |
|---|
| 1054 | + hw_dev->sw_reg = devm_kzalloc(dev, RKISP_ISP_SW_REG_SIZE * mult, GFP_KERNEL); |
|---|
| 1055 | + if (!hw_dev->sw_reg) |
|---|
| 1056 | + return -ENOMEM; |
|---|
| 862 | 1057 | dev_set_drvdata(dev, hw_dev); |
|---|
| 863 | 1058 | hw_dev->dev = dev; |
|---|
| 864 | 1059 | hw_dev->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP); |
|---|
| 865 | 1060 | dev_info(dev, "is_thunderboot: %d\n", hw_dev->is_thunderboot); |
|---|
| 866 | | - memset(&hw_dev->max_in, 0, sizeof(hw_dev->max_in)); |
|---|
| 867 | | - if (!of_property_read_u32_array(node, "max-input", &hw_dev->max_in.w, 3)) { |
|---|
| 868 | | - hw_dev->max_in.is_fix = true; |
|---|
| 869 | | - if (hw_dev->is_unite) { |
|---|
| 870 | | - hw_dev->max_in.w /= 2; |
|---|
| 871 | | - hw_dev->max_in.w += RKMOUDLE_UNITE_EXTEND_PIXEL; |
|---|
| 872 | | - } |
|---|
| 873 | | - } |
|---|
| 874 | | - dev_info(dev, "max input:%dx%d@%dfps\n", |
|---|
| 875 | | - hw_dev->max_in.w, hw_dev->max_in.h, hw_dev->max_in.fps); |
|---|
| 1061 | + |
|---|
| 876 | 1062 | hw_dev->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf"); |
|---|
| 877 | 1063 | if (IS_ERR(hw_dev->grf)) |
|---|
| 878 | 1064 | dev_warn(dev, "Missing rockchip,grf property\n"); |
|---|
| .. | .. |
|---|
| 919 | 1105 | } |
|---|
| 920 | 1106 | } |
|---|
| 921 | 1107 | |
|---|
| 1108 | + hw_dev->isp_ver = match_data->isp_ver; |
|---|
| 1109 | + if (match_data->unite) { |
|---|
| 1110 | + hw_dev->unite = ISP_UNITE_TWO; |
|---|
| 1111 | + } else if (device_property_read_bool(dev, "rockchip,unite-en")) { |
|---|
| 1112 | + hw_dev->unite = ISP_UNITE_ONE; |
|---|
| 1113 | + hw_dev->base_next_addr = hw_dev->base_addr; |
|---|
| 1114 | + } else { |
|---|
| 1115 | + hw_dev->unite = ISP_UNITE_NONE; |
|---|
| 1116 | + } |
|---|
| 1117 | + |
|---|
| 1118 | + memset(&hw_dev->max_in, 0, sizeof(hw_dev->max_in)); |
|---|
| 1119 | + if (!of_property_read_u32_array(node, "max-input", &hw_dev->max_in.w, 3)) { |
|---|
| 1120 | + hw_dev->max_in.is_fix = true; |
|---|
| 1121 | + if (hw_dev->unite) { |
|---|
| 1122 | + hw_dev->max_in.w /= 2; |
|---|
| 1123 | + hw_dev->max_in.w += RKMOUDLE_UNITE_EXTEND_PIXEL; |
|---|
| 1124 | + } |
|---|
| 1125 | + } |
|---|
| 1126 | + dev_info(dev, "max input:%dx%d@%dfps\n", |
|---|
| 1127 | + hw_dev->max_in.w, hw_dev->max_in.h, hw_dev->max_in.fps); |
|---|
| 1128 | + |
|---|
| 922 | 1129 | rkisp_monitor = device_property_read_bool(dev, "rockchip,restart-monitor-en"); |
|---|
| 923 | 1130 | hw_dev->mipi_irq = -1; |
|---|
| 924 | 1131 | |
|---|
| .. | .. |
|---|
| 941 | 1148 | hw_dev->clk_rate_tbl = match_data->clk_rate_tbl; |
|---|
| 942 | 1149 | hw_dev->num_clk_rate_tbl = match_data->num_clk_rate_tbl; |
|---|
| 943 | 1150 | |
|---|
| 1151 | + hw_dev->is_assigned_clk = false; |
|---|
| 1152 | + ret = of_property_read_u32(node, "assigned-clock-rates", &clk_rate); |
|---|
| 1153 | + if (!ret && clk_rate) |
|---|
| 1154 | + hw_dev->is_assigned_clk = true; |
|---|
| 1155 | + |
|---|
| 944 | 1156 | hw_dev->reset = devm_reset_control_array_get(dev, false, false); |
|---|
| 945 | 1157 | if (IS_ERR(hw_dev->reset)) { |
|---|
| 946 | 1158 | dev_dbg(dev, "failed to get reset\n"); |
|---|
| .. | .. |
|---|
| 959 | 1171 | hw_dev->dev_link_num = 0; |
|---|
| 960 | 1172 | hw_dev->cur_dev_id = 0; |
|---|
| 961 | 1173 | hw_dev->mipi_dev_id = 0; |
|---|
| 962 | | - hw_dev->pre_dev_id = 0; |
|---|
| 1174 | + hw_dev->pre_dev_id = -1; |
|---|
| 963 | 1175 | hw_dev->is_multi_overflow = false; |
|---|
| 964 | | - hw_dev->isp_ver = match_data->isp_ver; |
|---|
| 965 | | - hw_dev->is_unite = match_data->unite; |
|---|
| 966 | 1176 | mutex_init(&hw_dev->dev_lock); |
|---|
| 967 | 1177 | spin_lock_init(&hw_dev->rdbk_lock); |
|---|
| 968 | 1178 | atomic_set(&hw_dev->refcnt, 0); |
|---|
| .. | .. |
|---|
| 1012 | 1222 | hw_dev->is_shutdown = true; |
|---|
| 1013 | 1223 | if (pm_runtime_active(&pdev->dev)) { |
|---|
| 1014 | 1224 | writel(0xffff, hw_dev->base_addr + CIF_IRCL); |
|---|
| 1015 | | - if (hw_dev->is_unite) |
|---|
| 1225 | + if (hw_dev->unite == ISP_UNITE_TWO) |
|---|
| 1016 | 1226 | writel(0xffff, hw_dev->base_next_addr + CIF_IRCL); |
|---|
| 1017 | 1227 | } |
|---|
| 1018 | 1228 | dev_info(&pdev->dev, "%s\n", __func__); |
|---|
| .. | .. |
|---|
| 1021 | 1231 | static int __maybe_unused rkisp_runtime_suspend(struct device *dev) |
|---|
| 1022 | 1232 | { |
|---|
| 1023 | 1233 | struct rkisp_hw_dev *hw_dev = dev_get_drvdata(dev); |
|---|
| 1234 | + int i; |
|---|
| 1024 | 1235 | |
|---|
| 1025 | | - hw_dev->dev_link_num = 0; |
|---|
| 1026 | | - hw_dev->is_single = true; |
|---|
| 1027 | | - hw_dev->is_multi_overflow = false; |
|---|
| 1028 | | - hw_dev->is_frm_buf = false; |
|---|
| 1236 | + hw_dev->is_idle = true; |
|---|
| 1237 | + if (dev->power.runtime_status) { |
|---|
| 1238 | + hw_dev->dev_link_num = 0; |
|---|
| 1239 | + hw_dev->is_single = true; |
|---|
| 1240 | + hw_dev->is_multi_overflow = false; |
|---|
| 1241 | + hw_dev->is_frm_buf = false; |
|---|
| 1242 | + } else { |
|---|
| 1243 | + /* system suspend */ |
|---|
| 1244 | + for (i = 0; i < hw_dev->dev_num; i++) { |
|---|
| 1245 | + if (hw_dev->isp_size[i].is_on) { |
|---|
| 1246 | + rkisp_hw_reg_save(hw_dev); |
|---|
| 1247 | + break; |
|---|
| 1248 | + } |
|---|
| 1249 | + } |
|---|
| 1250 | + } |
|---|
| 1029 | 1251 | disable_sys_clk(hw_dev); |
|---|
| 1030 | 1252 | return pinctrl_pm_select_sleep_state(dev); |
|---|
| 1031 | 1253 | } |
|---|
| .. | .. |
|---|
| 1035 | 1257 | struct rkisp_device *isp; |
|---|
| 1036 | 1258 | u32 w, h, i; |
|---|
| 1037 | 1259 | |
|---|
| 1038 | | - memset(hw_dev->isp_size, 0, sizeof(hw_dev->isp_size)); |
|---|
| 1039 | 1260 | if (!hw_dev->max_in.is_fix) { |
|---|
| 1040 | 1261 | hw_dev->max_in.w = 0; |
|---|
| 1041 | 1262 | hw_dev->max_in.h = 0; |
|---|
| .. | .. |
|---|
| 1052 | 1273 | hw_dev->is_single = false; |
|---|
| 1053 | 1274 | w = isp->isp_sdev.in_crop.width; |
|---|
| 1054 | 1275 | h = isp->isp_sdev.in_crop.height; |
|---|
| 1055 | | - if (hw_dev->is_unite) |
|---|
| 1276 | + if (hw_dev->unite) |
|---|
| 1056 | 1277 | w = w / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; |
|---|
| 1057 | 1278 | hw_dev->isp_size[i].w = w; |
|---|
| 1058 | 1279 | hw_dev->isp_size[i].h = h; |
|---|
| .. | .. |
|---|
| 1064 | 1285 | hw_dev->max_in.h = h; |
|---|
| 1065 | 1286 | } |
|---|
| 1066 | 1287 | } |
|---|
| 1288 | + if (hw_dev->unite == ISP_UNITE_ONE) |
|---|
| 1289 | + hw_dev->is_single = false; |
|---|
| 1067 | 1290 | for (i = 0; i < hw_dev->dev_num; i++) { |
|---|
| 1068 | 1291 | isp = hw_dev->isp[i]; |
|---|
| 1069 | 1292 | if (!isp || (isp && !isp->is_hw_link)) |
|---|
| .. | .. |
|---|
| 1077 | 1300 | struct rkisp_hw_dev *hw_dev = dev_get_drvdata(dev); |
|---|
| 1078 | 1301 | void __iomem *base = hw_dev->base_addr; |
|---|
| 1079 | 1302 | struct rkisp_device *isp; |
|---|
| 1080 | | - int mult = hw_dev->is_unite ? 2 : 1; |
|---|
| 1303 | + int mult = hw_dev->unite ? 2 : 1; |
|---|
| 1081 | 1304 | int ret, i; |
|---|
| 1082 | 1305 | void *buf; |
|---|
| 1083 | 1306 | |
|---|
| .. | .. |
|---|
| 1086 | 1309 | return ret; |
|---|
| 1087 | 1310 | |
|---|
| 1088 | 1311 | enable_sys_clk(hw_dev); |
|---|
| 1089 | | - for (i = 0; i < hw_dev->dev_num; i++) { |
|---|
| 1090 | | - isp = hw_dev->isp[i]; |
|---|
| 1091 | | - if (!isp || !isp->sw_base_addr) |
|---|
| 1092 | | - continue; |
|---|
| 1093 | | - buf = isp->sw_base_addr; |
|---|
| 1094 | | - memset(buf, 0, RKISP_ISP_SW_MAX_SIZE * mult); |
|---|
| 1095 | | - memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE); |
|---|
| 1096 | | - if (hw_dev->is_unite) { |
|---|
| 1097 | | - buf += RKISP_ISP_SW_MAX_SIZE; |
|---|
| 1098 | | - base = hw_dev->base_next_addr; |
|---|
| 1099 | | - memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE); |
|---|
| 1312 | + if (dev->power.runtime_status) { |
|---|
| 1313 | + if (!hw_dev->is_assigned_clk) { |
|---|
| 1314 | + unsigned long rate = hw_dev->clk_rate_tbl[0].clk_rate * 1000000UL; |
|---|
| 1315 | + |
|---|
| 1316 | + rkisp_set_clk_rate(hw_dev->clks[0], rate); |
|---|
| 1317 | + if (hw_dev->unite == ISP_UNITE_TWO) |
|---|
| 1318 | + rkisp_set_clk_rate(hw_dev->clks[5], rate); |
|---|
| 1100 | 1319 | } |
|---|
| 1101 | | - default_sw_reg_flag(hw_dev->isp[i]); |
|---|
| 1320 | + for (i = 0; i < hw_dev->dev_num; i++) { |
|---|
| 1321 | + isp = hw_dev->isp[i]; |
|---|
| 1322 | + if (!isp || !isp->sw_base_addr) |
|---|
| 1323 | + continue; |
|---|
| 1324 | + buf = isp->sw_base_addr; |
|---|
| 1325 | + memset(buf, 0, RKISP_ISP_SW_MAX_SIZE * mult); |
|---|
| 1326 | + memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE); |
|---|
| 1327 | + if (hw_dev->unite) { |
|---|
| 1328 | + buf += RKISP_ISP_SW_MAX_SIZE; |
|---|
| 1329 | + base = hw_dev->base_next_addr; |
|---|
| 1330 | + memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE); |
|---|
| 1331 | + } |
|---|
| 1332 | + default_sw_reg_flag(hw_dev->isp[i]); |
|---|
| 1333 | + } |
|---|
| 1334 | + rkisp_hw_enum_isp_size(hw_dev); |
|---|
| 1335 | + hw_dev->monitor.is_en = rkisp_monitor; |
|---|
| 1336 | + } else { |
|---|
| 1337 | + /* system resume */ |
|---|
| 1338 | + for (i = 0; i < hw_dev->dev_num; i++) { |
|---|
| 1339 | + if (hw_dev->isp_size[i].is_on) { |
|---|
| 1340 | + rkisp_hw_reg_restore(hw_dev); |
|---|
| 1341 | + break; |
|---|
| 1342 | + } |
|---|
| 1343 | + } |
|---|
| 1102 | 1344 | } |
|---|
| 1103 | | - rkisp_hw_enum_isp_size(hw_dev); |
|---|
| 1104 | | - hw_dev->monitor.is_en = rkisp_monitor; |
|---|
| 1105 | 1345 | return 0; |
|---|
| 1106 | 1346 | } |
|---|
| 1107 | 1347 | |
|---|
| 1108 | 1348 | static const struct dev_pm_ops rkisp_hw_pm_ops = { |
|---|
| 1109 | | - SET_RUNTIME_PM_OPS(rkisp_runtime_suspend, |
|---|
| 1110 | | - rkisp_runtime_resume, NULL) |
|---|
| 1349 | + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) |
|---|
| 1350 | + SET_RUNTIME_PM_OPS(rkisp_runtime_suspend, rkisp_runtime_resume, NULL) |
|---|
| 1111 | 1351 | }; |
|---|
| 1112 | 1352 | |
|---|
| 1113 | 1353 | static struct platform_driver rkisp_hw_drv = { |
|---|