hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/media/platform/rockchip/isp/hw.c
....@@ -35,6 +35,12 @@
3535 * rkisp_hw
3636 */
3737
38
+struct backup_reg {
39
+ const u32 base;
40
+ const u32 shd;
41
+ u32 val;
42
+};
43
+
3844 struct isp_irqs_data {
3945 const char *name;
4046 irqreturn_t (*irq_hdl)(int irq, void *ctx);
....@@ -346,6 +352,192 @@
346352 }
347353
348354 return 0;
355
+}
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);
349541 }
350542
351543 static const char * const rk3562_isp_clks[] = {
....@@ -779,7 +971,6 @@
779971 static int enable_sys_clk(struct rkisp_hw_dev *dev)
780972 {
781973 int i, ret = -EINVAL;
782
- unsigned long rate;
783974
784975 for (i = 0; i < dev->num_clks; i++) {
785976 if (!IS_ERR(dev->clks[i])) {
....@@ -789,12 +980,6 @@
789980 }
790981 }
791982
792
- if (!dev->is_assigned_clk) {
793
- rate = dev->clk_rate_tbl[0].clk_rate * 1000000UL;
794
- rkisp_set_clk_rate(dev->clks[0], rate);
795
- if (dev->unite == ISP_UNITE_TWO)
796
- rkisp_set_clk_rate(dev->clks[5], rate);
797
- }
798983 rkisp_soft_reset(dev, false);
799984 isp_config_clk(dev, true);
800985 return 0;
....@@ -851,19 +1036,24 @@
8511036 struct device *dev = &pdev->dev;
8521037 struct rkisp_hw_dev *hw_dev;
8531038 struct resource *res;
854
- int i, ret;
1039
+ int i, ret, mult = 1;
8551040 bool is_mem_reserved = true;
8561041 u32 clk_rate = 0;
8571042
8581043 match = of_match_node(rkisp_hw_of_match, node);
8591044 if (IS_ERR(match))
8601045 return PTR_ERR(match);
1046
+ match_data = match->data;
8611047
8621048 hw_dev = devm_kzalloc(dev, sizeof(*hw_dev), GFP_KERNEL);
8631049 if (!hw_dev)
8641050 return -ENOMEM;
8651051
866
- match_data = match->data;
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;
8671057 dev_set_drvdata(dev, hw_dev);
8681058 hw_dev->dev = dev;
8691059 hw_dev->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
....@@ -1041,11 +1231,23 @@
10411231 static int __maybe_unused rkisp_runtime_suspend(struct device *dev)
10421232 {
10431233 struct rkisp_hw_dev *hw_dev = dev_get_drvdata(dev);
1234
+ int i;
10441235
1045
- hw_dev->dev_link_num = 0;
1046
- hw_dev->is_single = true;
1047
- hw_dev->is_multi_overflow = false;
1048
- 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
+ }
10491251 disable_sys_clk(hw_dev);
10501252 return pinctrl_pm_select_sleep_state(dev);
10511253 }
....@@ -1055,7 +1257,6 @@
10551257 struct rkisp_device *isp;
10561258 u32 w, h, i;
10571259
1058
- memset(hw_dev->isp_size, 0, sizeof(hw_dev->isp_size));
10591260 if (!hw_dev->max_in.is_fix) {
10601261 hw_dev->max_in.w = 0;
10611262 hw_dev->max_in.h = 0;
....@@ -1108,28 +1309,45 @@
11081309 return ret;
11091310
11101311 enable_sys_clk(hw_dev);
1111
- for (i = 0; i < hw_dev->dev_num; i++) {
1112
- isp = hw_dev->isp[i];
1113
- if (!isp || !isp->sw_base_addr)
1114
- continue;
1115
- buf = isp->sw_base_addr;
1116
- memset(buf, 0, RKISP_ISP_SW_MAX_SIZE * mult);
1117
- memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE);
1118
- if (hw_dev->unite) {
1119
- buf += RKISP_ISP_SW_MAX_SIZE;
1120
- base = hw_dev->base_next_addr;
1121
- 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);
11221319 }
1123
- 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
+ }
11241344 }
1125
- rkisp_hw_enum_isp_size(hw_dev);
1126
- hw_dev->monitor.is_en = rkisp_monitor;
11271345 return 0;
11281346 }
11291347
11301348 static const struct dev_pm_ops rkisp_hw_pm_ops = {
1131
- SET_RUNTIME_PM_OPS(rkisp_runtime_suspend,
1132
- 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)
11331351 };
11341352
11351353 static struct platform_driver rkisp_hw_drv = {