.. | .. |
---|
8 | 8 | #include <linux/delay.h> |
---|
9 | 9 | #include <linux/interrupt.h> |
---|
10 | 10 | #include <linux/module.h> |
---|
| 11 | +#include <linux/nvmem-consumer.h> |
---|
11 | 12 | #include <linux/of.h> |
---|
12 | 13 | #include <linux/of_gpio.h> |
---|
13 | 14 | #include <linux/of_graph.h> |
---|
.. | .. |
---|
22 | 23 | #include <media/videobuf2-dma-sg.h> |
---|
23 | 24 | #include <media/v4l2-fwnode.h> |
---|
24 | 25 | #include <linux/iommu.h> |
---|
25 | | -#include <dt-bindings/soc/rockchip-system-status.h> |
---|
26 | 26 | #include <soc/rockchip/rockchip-system-status.h> |
---|
27 | 27 | #include <linux/io.h> |
---|
28 | 28 | #include <linux/mfd/syscon.h> |
---|
.. | .. |
---|
698 | 698 | [CIF_REG_MIPI_EFFECT_CODE_ID1] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID1), |
---|
699 | 699 | [CIF_REG_MIPI_EFFECT_CODE_ID2] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID2), |
---|
700 | 700 | [CIF_REG_MIPI_EFFECT_CODE_ID3] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID3), |
---|
| 701 | + [CIF_REG_MIPI_FRAME_SIZE_ID0] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID0), |
---|
| 702 | + [CIF_REG_MIPI_FRAME_SIZE_ID1] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID1), |
---|
| 703 | + [CIF_REG_MIPI_FRAME_SIZE_ID2] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID2), |
---|
| 704 | + [CIF_REG_MIPI_FRAME_SIZE_ID3] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID3), |
---|
701 | 705 | [CIF_REG_MIPI_ON_PAD] = CIF_REG(CSI_MIPI0_ON_PAD), |
---|
702 | 706 | |
---|
703 | 707 | [CIF_REG_GLB_CTRL] = CIF_REG(GLB_CTRL), |
---|
.. | .. |
---|
822 | 826 | [CIF_REG_MIPI_EFFECT_CODE_ID1] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID1), |
---|
823 | 827 | [CIF_REG_MIPI_EFFECT_CODE_ID2] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID2), |
---|
824 | 828 | [CIF_REG_MIPI_EFFECT_CODE_ID3] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID3), |
---|
| 829 | + [CIF_REG_MIPI_FRAME_SIZE_ID0] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID0), |
---|
| 830 | + [CIF_REG_MIPI_FRAME_SIZE_ID1] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID1), |
---|
| 831 | + [CIF_REG_MIPI_FRAME_SIZE_ID2] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID2), |
---|
| 832 | + [CIF_REG_MIPI_FRAME_SIZE_ID3] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID3), |
---|
825 | 833 | [CIF_REG_MIPI_ON_PAD] = CIF_REG(CSI_MIPI0_ON_PAD), |
---|
826 | 834 | [CIF_REG_LVDS_ID0_CTRL0] = CIF_REG(CIF_LVDS0_ID0_CTRL0), |
---|
827 | 835 | [CIF_REG_LVDS_ID1_CTRL0] = CIF_REG(CIF_LVDS0_ID1_CTRL0), |
---|
.. | .. |
---|
941 | 949 | [CIF_REG_MIPI_EFFECT_CODE_ID1] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID1), |
---|
942 | 950 | [CIF_REG_MIPI_EFFECT_CODE_ID2] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID2), |
---|
943 | 951 | [CIF_REG_MIPI_EFFECT_CODE_ID3] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID3), |
---|
| 952 | + [CIF_REG_MIPI_FRAME_SIZE_ID0] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID0), |
---|
| 953 | + [CIF_REG_MIPI_FRAME_SIZE_ID1] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID1), |
---|
| 954 | + [CIF_REG_MIPI_FRAME_SIZE_ID2] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID2), |
---|
| 955 | + [CIF_REG_MIPI_FRAME_SIZE_ID3] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID3), |
---|
944 | 956 | [CIF_REG_MIPI_ON_PAD] = CIF_REG(CSI_MIPI0_ON_PAD), |
---|
945 | 957 | |
---|
946 | 958 | [CIF_REG_GLB_CTRL] = CIF_REG(GLB_CTRL), |
---|
.. | .. |
---|
1252 | 1264 | rkcif_iommu_enable(cif_hw); |
---|
1253 | 1265 | } |
---|
1254 | 1266 | |
---|
| 1267 | +static int rkcif_get_efuse_value(struct device_node *np, char *porp_name, |
---|
| 1268 | + u8 *value) |
---|
| 1269 | +{ |
---|
| 1270 | + struct nvmem_cell *cell; |
---|
| 1271 | + unsigned char *buf; |
---|
| 1272 | + size_t len; |
---|
| 1273 | + |
---|
| 1274 | + cell = of_nvmem_cell_get(np, porp_name); |
---|
| 1275 | + if (IS_ERR(cell)) |
---|
| 1276 | + return PTR_ERR(cell); |
---|
| 1277 | + |
---|
| 1278 | + buf = (unsigned char *)nvmem_cell_read(cell, &len); |
---|
| 1279 | + |
---|
| 1280 | + nvmem_cell_put(cell); |
---|
| 1281 | + |
---|
| 1282 | + if (IS_ERR(buf)) |
---|
| 1283 | + return PTR_ERR(buf); |
---|
| 1284 | + |
---|
| 1285 | + *value = buf[0]; |
---|
| 1286 | + |
---|
| 1287 | + kfree(buf); |
---|
| 1288 | + |
---|
| 1289 | + return 0; |
---|
| 1290 | +} |
---|
| 1291 | + |
---|
| 1292 | +static int rkcif_get_speciand_package_number(struct device_node *np) |
---|
| 1293 | +{ |
---|
| 1294 | + u8 spec = 0, package = 0, low = 0, high = 0; |
---|
| 1295 | + |
---|
| 1296 | + if (rkcif_get_efuse_value(np, "specification", &spec)) |
---|
| 1297 | + return -EINVAL; |
---|
| 1298 | + if (rkcif_get_efuse_value(np, "package_low", &low)) |
---|
| 1299 | + return -EINVAL; |
---|
| 1300 | + if (rkcif_get_efuse_value(np, "package_high", &high)) |
---|
| 1301 | + return -EINVAL; |
---|
| 1302 | + |
---|
| 1303 | + package = ((high & 0x1) << 3) | low; |
---|
| 1304 | + |
---|
| 1305 | + /* RK3588S */ |
---|
| 1306 | + if (spec == 0x13) |
---|
| 1307 | + return package; |
---|
| 1308 | + |
---|
| 1309 | + return -EINVAL; |
---|
| 1310 | +} |
---|
| 1311 | + |
---|
1255 | 1312 | static int rkcif_plat_hw_probe(struct platform_device *pdev) |
---|
1256 | 1313 | { |
---|
1257 | 1314 | const struct of_device_id *match; |
---|
.. | .. |
---|
1265 | 1322 | int i, ret, irq; |
---|
1266 | 1323 | bool is_mem_reserved = false; |
---|
1267 | 1324 | struct notifier_block *notifier; |
---|
| 1325 | + int package = 0; |
---|
1268 | 1326 | |
---|
1269 | 1327 | match = of_match_node(rkcif_plat_of_match, node); |
---|
1270 | 1328 | if (IS_ERR(match)) |
---|
.. | .. |
---|
1278 | 1336 | dev_set_drvdata(dev, cif_hw); |
---|
1279 | 1337 | cif_hw->dev = dev; |
---|
1280 | 1338 | |
---|
| 1339 | + package = rkcif_get_speciand_package_number(node); |
---|
| 1340 | + if (package == 0x2) { |
---|
| 1341 | + cif_hw->is_rk3588s2 = true; |
---|
| 1342 | + dev_info(dev, "attach rk3588s2\n"); |
---|
| 1343 | + } else { |
---|
| 1344 | + cif_hw->is_rk3588s2 = false; |
---|
| 1345 | + } |
---|
1281 | 1346 | irq = platform_get_irq(pdev, 0); |
---|
1282 | 1347 | if (irq < 0) |
---|
1283 | 1348 | return irq; |
---|
.. | .. |
---|
1484 | 1549 | return 0; |
---|
1485 | 1550 | } |
---|
1486 | 1551 | |
---|
| 1552 | +static int __maybe_unused rkcif_sleep_suspend(struct device *dev) |
---|
| 1553 | +{ |
---|
| 1554 | + struct rkcif_hw *cif_hw = dev_get_drvdata(dev); |
---|
| 1555 | + |
---|
| 1556 | + if (atomic_read(&cif_hw->power_cnt) == 0) |
---|
| 1557 | + return 0; |
---|
| 1558 | + |
---|
| 1559 | + rkcif_disable_sys_clk(cif_hw); |
---|
| 1560 | + |
---|
| 1561 | + return pinctrl_pm_select_sleep_state(dev); |
---|
| 1562 | +} |
---|
| 1563 | + |
---|
| 1564 | +static int __maybe_unused rkcif_sleep_resume(struct device *dev) |
---|
| 1565 | +{ |
---|
| 1566 | + struct rkcif_hw *cif_hw = dev_get_drvdata(dev); |
---|
| 1567 | + int ret; |
---|
| 1568 | + |
---|
| 1569 | + if (atomic_read(&cif_hw->power_cnt) == 0) |
---|
| 1570 | + return 0; |
---|
| 1571 | + |
---|
| 1572 | + ret = pinctrl_pm_select_default_state(dev); |
---|
| 1573 | + if (ret < 0) |
---|
| 1574 | + return ret; |
---|
| 1575 | + rkcif_enable_sys_clk(cif_hw); |
---|
| 1576 | + rkcif_hw_soft_reset(cif_hw, true); |
---|
| 1577 | + |
---|
| 1578 | + return 0; |
---|
| 1579 | +} |
---|
| 1580 | + |
---|
1487 | 1581 | static const struct dev_pm_ops rkcif_plat_pm_ops = { |
---|
| 1582 | + SET_LATE_SYSTEM_SLEEP_PM_OPS(rkcif_sleep_suspend, |
---|
| 1583 | + rkcif_sleep_resume) |
---|
1488 | 1584 | SET_RUNTIME_PM_OPS(rkcif_runtime_suspend, rkcif_runtime_resume, NULL) |
---|
1489 | 1585 | }; |
---|
1490 | 1586 | |
---|
.. | .. |
---|
1506 | 1602 | ret = platform_driver_register(&rkcif_hw_plat_drv); |
---|
1507 | 1603 | if (ret) |
---|
1508 | 1604 | return ret; |
---|
| 1605 | + rkcif_csi2_hw_plat_drv_init(); |
---|
1509 | 1606 | return rkcif_csi2_plat_drv_init(); |
---|
1510 | 1607 | } |
---|
1511 | 1608 | |
---|
.. | .. |
---|
1513 | 1610 | { |
---|
1514 | 1611 | platform_driver_unregister(&rkcif_hw_plat_drv); |
---|
1515 | 1612 | rkcif_csi2_plat_drv_exit(); |
---|
| 1613 | + rkcif_csi2_hw_plat_drv_exit(); |
---|
1516 | 1614 | } |
---|
1517 | 1615 | |
---|
1518 | 1616 | #if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC) |
---|