13d0407baSopenharmony_ci// SPDX-License-Identifier: GPL-2.0
23d0407baSopenharmony_ci/*
33d0407baSopenharmony_ci * Rockchip MIPI CSI2 DPHY driver
43d0407baSopenharmony_ci *
53d0407baSopenharmony_ci * Copyright (C) 2022 Rockchip Electronics Co., Ltd.
63d0407baSopenharmony_ci */
73d0407baSopenharmony_ci
83d0407baSopenharmony_ci#include <linux/clk.h>
93d0407baSopenharmony_ci#include <linux/delay.h>
103d0407baSopenharmony_ci#include <linux/io.h>
113d0407baSopenharmony_ci#include <linux/module.h>
123d0407baSopenharmony_ci#include <linux/of.h>
133d0407baSopenharmony_ci#include <linux/of_graph.h>
143d0407baSopenharmony_ci#include <linux/of_platform.h>
153d0407baSopenharmony_ci#include <linux/platform_device.h>
163d0407baSopenharmony_ci#include <linux/pm_runtime.h>
173d0407baSopenharmony_ci#include <linux/regmap.h>
183d0407baSopenharmony_ci#include <linux/mfd/syscon.h>
193d0407baSopenharmony_ci#include <media/media-entity.h>
203d0407baSopenharmony_ci#include <media/v4l2-ctrls.h>
213d0407baSopenharmony_ci#include <media/v4l2-fwnode.h>
223d0407baSopenharmony_ci#include <media/v4l2-subdev.h>
233d0407baSopenharmony_ci#include <media/v4l2-device.h>
243d0407baSopenharmony_ci#include <linux/reset.h>
253d0407baSopenharmony_ci#include "phy-rockchip-csi2-dphy-common.h"
263d0407baSopenharmony_ci
273d0407baSopenharmony_ci/* GRF REG OFFSET */
283d0407baSopenharmony_ci#define GRF_VI_CON0 (0x0340)
293d0407baSopenharmony_ci#define GRF_VI_CON1 (0x0344)
303d0407baSopenharmony_ci
313d0407baSopenharmony_ci/* RK3588 DPHY GRF REG OFFSET */
323d0407baSopenharmony_ci#define GRF_DPHY_CON0 (0x0)
333d0407baSopenharmony_ci#define GRF_SOC_CON2 (0x0308)
343d0407baSopenharmony_ci
353d0407baSopenharmony_ci/* GRF REG BIT DEFINE */
363d0407baSopenharmony_ci#define GRF_CSI2PHY_LANE_SEL_SPLIT (0x1)
373d0407baSopenharmony_ci#define GRF_CSI2PHY_SEL_SPLIT_0_1 (0x0)
383d0407baSopenharmony_ci#define GRF_CSI2PHY_SEL_SPLIT_2_3 BIT(0)
393d0407baSopenharmony_ci
403d0407baSopenharmony_ci/* RK3588 DCPHY GRF REG OFFSET */
413d0407baSopenharmony_ci#define GRF_DCPHY_CON0 (0x0)
423d0407baSopenharmony_ci
433d0407baSopenharmony_ci/* PHY REG OFFSET */
443d0407baSopenharmony_ci#define CSI2_DPHY_CTRL_INVALID_OFFSET (0xffff)
453d0407baSopenharmony_ci#define CSI2_DPHY_CTRL_PWRCTL CSI2_DPHY_CTRL_INVALID_OFFSET
463d0407baSopenharmony_ci#define CSI2_DPHY_CTRL_LANE_ENABLE (0x00)
473d0407baSopenharmony_ci#define CSI2_DPHY_CLK1_LANE_EN (0x2C)
483d0407baSopenharmony_ci#define CSI2_DPHY_DUAL_CAL_EN (0x80)
493d0407baSopenharmony_ci#define CSI2_DPHY_CLK_WR_THS_SETTLE (0x160)
503d0407baSopenharmony_ci#define CSI2_DPHY_CLK_CALIB_EN (0x168)
513d0407baSopenharmony_ci#define CSI2_DPHY_LANE0_WR_THS_SETTLE (0x1e0)
523d0407baSopenharmony_ci#define CSI2_DPHY_LANE0_CALIB_EN (0x1e8)
533d0407baSopenharmony_ci#define CSI2_DPHY_LANE1_WR_THS_SETTLE (0x260)
543d0407baSopenharmony_ci#define CSI2_DPHY_LANE1_CALIB_EN (0x268)
553d0407baSopenharmony_ci#define CSI2_DPHY_LANE2_WR_THS_SETTLE (0x2e0)
563d0407baSopenharmony_ci#define CSI2_DPHY_LANE2_CALIB_EN (0x2e8)
573d0407baSopenharmony_ci#define CSI2_DPHY_LANE3_WR_THS_SETTLE (0x360)
583d0407baSopenharmony_ci#define CSI2_DPHY_LANE3_CALIB_EN (0x368)
593d0407baSopenharmony_ci#define CSI2_DPHY_CLK1_WR_THS_SETTLE (0x3e0)
603d0407baSopenharmony_ci#define CSI2_DPHY_CLK1_CALIB_EN (0x3e8)
613d0407baSopenharmony_ci
623d0407baSopenharmony_ci#define CSI2_DCPHY_CLK_WR_THS_SETTLE (0x030)
633d0407baSopenharmony_ci#define CSI2_DCPHY_LANE0_WR_THS_SETTLE (0x130)
643d0407baSopenharmony_ci#define CSI2_DCPHY_LANE0_WR_ERR_SOT_SYNC (0x134)
653d0407baSopenharmony_ci#define CSI2_DCPHY_LANE1_WR_THS_SETTLE (0x230)
663d0407baSopenharmony_ci#define CSI2_DCPHY_LANE1_WR_ERR_SOT_SYNC (0x234)
673d0407baSopenharmony_ci#define CSI2_DCPHY_LANE2_WR_THS_SETTLE (0x330)
683d0407baSopenharmony_ci#define CSI2_DCPHY_LANE2_WR_ERR_SOT_SYNC (0x334)
693d0407baSopenharmony_ci#define CSI2_DCPHY_LANE3_WR_THS_SETTLE (0x430)
703d0407baSopenharmony_ci#define CSI2_DCPHY_LANE3_WR_ERR_SOT_SYNC (0x434)
713d0407baSopenharmony_ci#define CSI2_DCPHY_CLK_LANE_ENABLE (0x000)
723d0407baSopenharmony_ci#define CSI2_DCPHY_DATA_LANE0_ENABLE (0x100)
733d0407baSopenharmony_ci#define CSI2_DCPHY_DATA_LANE1_ENABLE (0x200)
743d0407baSopenharmony_ci#define CSI2_DCPHY_DATA_LANE2_ENABLE (0x300)
753d0407baSopenharmony_ci#define CSI2_DCPHY_DATA_LANE3_ENABLE (0x400)
763d0407baSopenharmony_ci
773d0407baSopenharmony_ci#define CSI2_DCPHY_S0C_GNR_CON1 (0x004)
783d0407baSopenharmony_ci#define CSI2_DCPHY_COMBO_S0D0_GNR_CON1 (0x104)
793d0407baSopenharmony_ci#define CSI2_DCPHY_COMBO_S0D1_GNR_CON1 (0x204)
803d0407baSopenharmony_ci#define CSI2_DCPHY_COMBO_S0D2_GNR_CON1 (0x304)
813d0407baSopenharmony_ci#define CSI2_DCPHY_S0D3_GNR_CON1 (0x304)
823d0407baSopenharmony_ci
833d0407baSopenharmony_ci/* PHY REG BIT DEFINE */
843d0407baSopenharmony_ci#define CSI2_DPHY_LANE_MODE_FULL (0x4)
853d0407baSopenharmony_ci#define CSI2_DPHY_LANE_MODE_SPLIT (0x2)
863d0407baSopenharmony_ci#define CSI2_DPHY_LANE_SPLIT_TOP (0x1)
873d0407baSopenharmony_ci#define CSI2_DPHY_LANE_SPLIT_BOT (0x2)
883d0407baSopenharmony_ci#define CSI2_DPHY_LANE_SPLIT_LANE0_1 (0x3 << 2)
893d0407baSopenharmony_ci#define CSI2_DPHY_LANE_SPLIT_LANE2_3 (0x3 << 4)
903d0407baSopenharmony_ci#define CSI2_DPHY_LANE_DUAL_MODE_EN BIT(6)
913d0407baSopenharmony_ci#define CSI2_DPHY_LANE_PARA_ARR_NUM (0x2)
923d0407baSopenharmony_ci
933d0407baSopenharmony_ci#define CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT 2
943d0407baSopenharmony_ci#define CSI2_DPHY_CTRL_DATALANE_SPLIT_LANE2_3_OFFSET_BIT 4
953d0407baSopenharmony_ci#define CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT 6
963d0407baSopenharmony_ci
973d0407baSopenharmony_cienum csi2_dphy_index {
983d0407baSopenharmony_ci    DPHY0 = 0x0,
993d0407baSopenharmony_ci    DPHY1,
1003d0407baSopenharmony_ci    DPHY2,
1013d0407baSopenharmony_ci};
1023d0407baSopenharmony_ci
1033d0407baSopenharmony_cienum csi2_dphy_lane {
1043d0407baSopenharmony_ci    CSI2_DPHY_LANE_CLOCK = 0,
1053d0407baSopenharmony_ci    CSI2_DPHY_LANE_CLOCK1,
1063d0407baSopenharmony_ci    CSI2_DPHY_LANE_DATA0,
1073d0407baSopenharmony_ci    CSI2_DPHY_LANE_DATA1,
1083d0407baSopenharmony_ci    CSI2_DPHY_LANE_DATA2,
1093d0407baSopenharmony_ci    CSI2_DPHY_LANE_DATA3
1103d0407baSopenharmony_ci};
1113d0407baSopenharmony_ci
1123d0407baSopenharmony_cienum grf_reg_id {
1133d0407baSopenharmony_ci    GRF_DPHY_RX0_TURNDISABLE = 0,
1143d0407baSopenharmony_ci    GRF_DPHY_RX0_FORCERXMODE,
1153d0407baSopenharmony_ci    GRF_DPHY_RX0_FORCETXSTOPMODE,
1163d0407baSopenharmony_ci    GRF_DPHY_RX0_ENABLE,
1173d0407baSopenharmony_ci    GRF_DPHY_RX0_TESTCLR,
1183d0407baSopenharmony_ci    GRF_DPHY_RX0_TESTCLK,
1193d0407baSopenharmony_ci    GRF_DPHY_RX0_TESTEN,
1203d0407baSopenharmony_ci    GRF_DPHY_RX0_TESTDIN,
1213d0407baSopenharmony_ci    GRF_DPHY_RX0_TURNREQUEST,
1223d0407baSopenharmony_ci    GRF_DPHY_RX0_TESTDOUT,
1233d0407baSopenharmony_ci    GRF_DPHY_TX0_TURNDISABLE,
1243d0407baSopenharmony_ci    GRF_DPHY_TX0_FORCERXMODE,
1253d0407baSopenharmony_ci    GRF_DPHY_TX0_FORCETXSTOPMODE,
1263d0407baSopenharmony_ci    GRF_DPHY_TX0_TURNREQUEST,
1273d0407baSopenharmony_ci    GRF_DPHY_TX1RX1_TURNDISABLE,
1283d0407baSopenharmony_ci    GRF_DPHY_TX1RX1_FORCERXMODE,
1293d0407baSopenharmony_ci    GRF_DPHY_TX1RX1_FORCETXSTOPMODE,
1303d0407baSopenharmony_ci    GRF_DPHY_TX1RX1_ENABLE,
1313d0407baSopenharmony_ci    GRF_DPHY_TX1RX1_MASTERSLAVEZ,
1323d0407baSopenharmony_ci    GRF_DPHY_TX1RX1_BASEDIR,
1333d0407baSopenharmony_ci    GRF_DPHY_TX1RX1_ENABLECLK,
1343d0407baSopenharmony_ci    GRF_DPHY_TX1RX1_TURNREQUEST,
1353d0407baSopenharmony_ci    GRF_DPHY_RX1_SRC_SEL,
1363d0407baSopenharmony_ci    /* rk3288 only */
1373d0407baSopenharmony_ci    GRF_CON_DISABLE_ISP,
1383d0407baSopenharmony_ci    GRF_CON_ISP_DPHY_SEL,
1393d0407baSopenharmony_ci    GRF_DSI_CSI_TESTBUS_SEL,
1403d0407baSopenharmony_ci    GRF_DVP_V18SEL,
1413d0407baSopenharmony_ci    /* rk1808 & rk3326 & rv1126 */
1423d0407baSopenharmony_ci    GRF_DPHY_CSI2PHY_FORCERXMODE,
1433d0407baSopenharmony_ci    GRF_DPHY_CSI2PHY_CLKLANE_EN,
1443d0407baSopenharmony_ci    GRF_DPHY_CSI2PHY_DATALANE_EN,
1453d0407baSopenharmony_ci    /* rv1126 only */
1463d0407baSopenharmony_ci    GRF_DPHY_CLK_INV_SEL,
1473d0407baSopenharmony_ci    GRF_DPHY_SEL,
1483d0407baSopenharmony_ci    /* rk3368 only */
1493d0407baSopenharmony_ci    GRF_ISP_MIPI_CSI_HOST_SEL,
1503d0407baSopenharmony_ci    /* below is for rk3399 only */
1513d0407baSopenharmony_ci    GRF_DPHY_RX0_CLK_INV_SEL,
1523d0407baSopenharmony_ci    GRF_DPHY_RX1_CLK_INV_SEL,
1533d0407baSopenharmony_ci    GRF_DPHY_TX1RX1_SRC_SEL,
1543d0407baSopenharmony_ci    /* below is for rk3568 only */
1553d0407baSopenharmony_ci    GRF_DPHY_CSI2PHY_CLKLANE1_EN,
1563d0407baSopenharmony_ci    GRF_DPHY_CLK1_INV_SEL,
1573d0407baSopenharmony_ci    GRF_DPHY_ISP_CSI2PHY_SEL,
1583d0407baSopenharmony_ci    GRF_DPHY_CIF_CSI2PHY_SEL,
1593d0407baSopenharmony_ci    GRF_DPHY_CSI2PHY_LANE_SEL,
1603d0407baSopenharmony_ci    GRF_DPHY_CSI2PHY1_LANE_SEL,
1613d0407baSopenharmony_ci    GRF_DPHY_CSI2PHY_DATALANE_EN0,
1623d0407baSopenharmony_ci    GRF_DPHY_CSI2PHY_DATALANE_EN1,
1633d0407baSopenharmony_ci    GRF_CPHY_MODE,
1643d0407baSopenharmony_ci    GRF_DPHY_CSIHOST2_SEL,
1653d0407baSopenharmony_ci    GRF_DPHY_CSIHOST3_SEL,
1663d0407baSopenharmony_ci    GRF_DPHY_CSIHOST4_SEL,
1673d0407baSopenharmony_ci    GRF_DPHY_CSIHOST5_SEL,
1683d0407baSopenharmony_ci};
1693d0407baSopenharmony_ci
1703d0407baSopenharmony_cienum csi2dphy_reg_id {
1713d0407baSopenharmony_ci    CSI2PHY_REG_CTRL_LANE_ENABLE = 0,
1723d0407baSopenharmony_ci    CSI2PHY_CTRL_PWRCTL,
1733d0407baSopenharmony_ci    CSI2PHY_CTRL_DIG_RST,
1743d0407baSopenharmony_ci    CSI2PHY_CLK_THS_SETTLE,
1753d0407baSopenharmony_ci    CSI2PHY_LANE0_THS_SETTLE,
1763d0407baSopenharmony_ci    CSI2PHY_LANE1_THS_SETTLE,
1773d0407baSopenharmony_ci    CSI2PHY_LANE2_THS_SETTLE,
1783d0407baSopenharmony_ci    CSI2PHY_LANE3_THS_SETTLE,
1793d0407baSopenharmony_ci    CSI2PHY_CLK_CALIB_ENABLE,
1803d0407baSopenharmony_ci    CSI2PHY_LANE0_CALIB_ENABLE,
1813d0407baSopenharmony_ci    CSI2PHY_LANE1_CALIB_ENABLE,
1823d0407baSopenharmony_ci    CSI2PHY_LANE2_CALIB_ENABLE,
1833d0407baSopenharmony_ci    CSI2PHY_LANE3_CALIB_ENABLE,
1843d0407baSopenharmony_ci    // rv1126 only
1853d0407baSopenharmony_ci    CSI2PHY_MIPI_LVDS_MODEL,
1863d0407baSopenharmony_ci    CSI2PHY_LVDS_MODE,
1873d0407baSopenharmony_ci    // rk3568 only
1883d0407baSopenharmony_ci    CSI2PHY_DUAL_CLK_EN,
1893d0407baSopenharmony_ci    CSI2PHY_CLK1_THS_SETTLE,
1903d0407baSopenharmony_ci    CSI2PHY_CLK1_CALIB_ENABLE,
1913d0407baSopenharmony_ci    // rk3588
1923d0407baSopenharmony_ci    CSI2PHY_CLK_LANE_ENABLE,
1933d0407baSopenharmony_ci    CSI2PHY_CLK1_LANE_ENABLE,
1943d0407baSopenharmony_ci    CSI2PHY_DATA_LANE0_ENABLE,
1953d0407baSopenharmony_ci    CSI2PHY_DATA_LANE1_ENABLE,
1963d0407baSopenharmony_ci    CSI2PHY_DATA_LANE2_ENABLE,
1973d0407baSopenharmony_ci    CSI2PHY_DATA_LANE3_ENABLE,
1983d0407baSopenharmony_ci    CSI2PHY_LANE0_ERR_SOT_SYNC,
1993d0407baSopenharmony_ci    CSI2PHY_LANE1_ERR_SOT_SYNC,
2003d0407baSopenharmony_ci    CSI2PHY_LANE2_ERR_SOT_SYNC,
2013d0407baSopenharmony_ci    CSI2PHY_LANE3_ERR_SOT_SYNC,
2023d0407baSopenharmony_ci    CSI2PHY_S0C_GNR_CON1,
2033d0407baSopenharmony_ci    CSI2PHY_COMBO_S0D0_GNR_CON1,
2043d0407baSopenharmony_ci    CSI2PHY_COMBO_S0D1_GNR_CON1,
2053d0407baSopenharmony_ci    CSI2PHY_COMBO_S0D2_GNR_CON1,
2063d0407baSopenharmony_ci    CSI2PHY_S0D3_GNR_CON1,
2073d0407baSopenharmony_ci};
2083d0407baSopenharmony_ci
2093d0407baSopenharmony_ci#define HIWORD_UPDATE(val, mask, shift) ((val) << (shift) | (mask) << ((shift) + 16))
2103d0407baSopenharmony_ci
2113d0407baSopenharmony_ci#define GRF_REG(_offset, _width, _shift)                                                                               \
2123d0407baSopenharmony_ci    {                                                                                                                  \
2133d0407baSopenharmony_ci        .offset = (_offset), .mask = BIT(_width) - 1, .shift = (_shift),                                               \
2143d0407baSopenharmony_ci    }
2153d0407baSopenharmony_ci
2163d0407baSopenharmony_ci#define CSI2PHY_REG(_offset)                                                                                           \
2173d0407baSopenharmony_ci    {                                                                                                                  \
2183d0407baSopenharmony_ci        .offset = (_offset),                                                                                           \
2193d0407baSopenharmony_ci    }
2203d0407baSopenharmony_ci
2213d0407baSopenharmony_cistruct hsfreq_range {
2223d0407baSopenharmony_ci    u32 range_h;
2233d0407baSopenharmony_ci    u16 cfg_bit;
2243d0407baSopenharmony_ci};
2253d0407baSopenharmony_ci
2263d0407baSopenharmony_cistatic inline void write_sys_grf_reg(struct csi2_dphy_hw *hw, int index, u8 value)
2273d0407baSopenharmony_ci{
2283d0407baSopenharmony_ci    const struct grf_reg *reg = &hw->grf_regs[index];
2293d0407baSopenharmony_ci    unsigned int val = HIWORD_UPDATE(value, reg->mask, reg->shift);
2303d0407baSopenharmony_ci
2313d0407baSopenharmony_ci    if (reg->shift) {
2323d0407baSopenharmony_ci        regmap_write(hw->regmap_sys_grf, reg->offset, val);
2333d0407baSopenharmony_ci    }
2343d0407baSopenharmony_ci}
2353d0407baSopenharmony_ci
2363d0407baSopenharmony_cistatic inline void write_grf_reg(struct csi2_dphy_hw *hw, int index, u8 value)
2373d0407baSopenharmony_ci{
2383d0407baSopenharmony_ci    const struct grf_reg *reg = &hw->grf_regs[index];
2393d0407baSopenharmony_ci    unsigned int val = HIWORD_UPDATE(value, reg->mask, reg->shift);
2403d0407baSopenharmony_ci
2413d0407baSopenharmony_ci    if (reg->shift) {
2423d0407baSopenharmony_ci        regmap_write(hw->regmap_grf, reg->offset, val);
2433d0407baSopenharmony_ci    }
2443d0407baSopenharmony_ci}
2453d0407baSopenharmony_ci
2463d0407baSopenharmony_cistatic inline u32 read_grf_reg(struct csi2_dphy_hw *hw, int index)
2473d0407baSopenharmony_ci{
2483d0407baSopenharmony_ci    const struct grf_reg *reg = &hw->grf_regs[index];
2493d0407baSopenharmony_ci    unsigned int val = 0;
2503d0407baSopenharmony_ci
2513d0407baSopenharmony_ci    if (reg->shift) {
2523d0407baSopenharmony_ci        regmap_read(hw->regmap_grf, reg->offset, &val);
2533d0407baSopenharmony_ci        val = (val >> reg->shift) & reg->mask;
2543d0407baSopenharmony_ci    }
2553d0407baSopenharmony_ci
2563d0407baSopenharmony_ci    return val;
2573d0407baSopenharmony_ci}
2583d0407baSopenharmony_ci
2593d0407baSopenharmony_cistatic inline void write_csi2_dphy_reg(struct csi2_dphy_hw *hw, int index, u32 value)
2603d0407baSopenharmony_ci{
2613d0407baSopenharmony_ci    const struct csi2dphy_reg *reg = &hw->csi2dphy_regs[index];
2623d0407baSopenharmony_ci
2633d0407baSopenharmony_ci    if ((index == CSI2PHY_REG_CTRL_LANE_ENABLE) || (index == CSI2PHY_CLK_LANE_ENABLE) ||
2643d0407baSopenharmony_ci        (index != CSI2PHY_REG_CTRL_LANE_ENABLE && reg->offset != 0x0)) {
2653d0407baSopenharmony_ci        writel(value, hw->hw_base_addr + reg->offset);
2663d0407baSopenharmony_ci    }
2673d0407baSopenharmony_ci}
2683d0407baSopenharmony_ci
2693d0407baSopenharmony_cistatic inline void write_csi2_dphy_reg_mask(struct csi2_dphy_hw *hw, int index, u32 value, u32 mask)
2703d0407baSopenharmony_ci{
2713d0407baSopenharmony_ci    const struct csi2dphy_reg *reg = &hw->csi2dphy_regs[index];
2723d0407baSopenharmony_ci    u32 read_val = 0;
2733d0407baSopenharmony_ci
2743d0407baSopenharmony_ci    read_val = readl(hw->hw_base_addr + reg->offset);
2753d0407baSopenharmony_ci    read_val &= ~mask;
2763d0407baSopenharmony_ci    read_val |= value;
2773d0407baSopenharmony_ci    writel(read_val, hw->hw_base_addr + reg->offset);
2783d0407baSopenharmony_ci}
2793d0407baSopenharmony_ci
2803d0407baSopenharmony_cistatic inline void read_csi2_dphy_reg(struct csi2_dphy_hw *hw, int index, u32 *value)
2813d0407baSopenharmony_ci{
2823d0407baSopenharmony_ci    const struct csi2dphy_reg *reg = &hw->csi2dphy_regs[index];
2833d0407baSopenharmony_ci
2843d0407baSopenharmony_ci    if ((index == CSI2PHY_REG_CTRL_LANE_ENABLE) || (index == CSI2PHY_CLK_LANE_ENABLE) ||
2853d0407baSopenharmony_ci        (index != CSI2PHY_REG_CTRL_LANE_ENABLE && reg->offset != 0x0)) {
2863d0407baSopenharmony_ci        *value = readl(hw->hw_base_addr + reg->offset);
2873d0407baSopenharmony_ci    }
2883d0407baSopenharmony_ci}
2893d0407baSopenharmony_ci
2903d0407baSopenharmony_cistatic void csi_mipidphy_wr_ths_settle(struct csi2_dphy_hw *hw, int hsfreq, enum csi2_dphy_lane lane)
2913d0407baSopenharmony_ci{
2923d0407baSopenharmony_ci    unsigned int val = 0;
2933d0407baSopenharmony_ci    unsigned int offset;
2943d0407baSopenharmony_ci
2953d0407baSopenharmony_ci    switch (lane) {
2963d0407baSopenharmony_ci        case CSI2_DPHY_LANE_CLOCK:
2973d0407baSopenharmony_ci            offset = CSI2PHY_CLK_THS_SETTLE;
2983d0407baSopenharmony_ci            break;
2993d0407baSopenharmony_ci        case CSI2_DPHY_LANE_CLOCK1:
3003d0407baSopenharmony_ci            offset = CSI2PHY_CLK1_THS_SETTLE;
3013d0407baSopenharmony_ci            break;
3023d0407baSopenharmony_ci        case CSI2_DPHY_LANE_DATA0:
3033d0407baSopenharmony_ci            offset = CSI2PHY_LANE0_THS_SETTLE;
3043d0407baSopenharmony_ci            break;
3053d0407baSopenharmony_ci        case CSI2_DPHY_LANE_DATA1:
3063d0407baSopenharmony_ci            offset = CSI2PHY_LANE1_THS_SETTLE;
3073d0407baSopenharmony_ci            break;
3083d0407baSopenharmony_ci        case CSI2_DPHY_LANE_DATA2:
3093d0407baSopenharmony_ci            offset = CSI2PHY_LANE2_THS_SETTLE;
3103d0407baSopenharmony_ci            break;
3113d0407baSopenharmony_ci        case CSI2_DPHY_LANE_DATA3:
3123d0407baSopenharmony_ci            offset = CSI2PHY_LANE3_THS_SETTLE;
3133d0407baSopenharmony_ci            break;
3143d0407baSopenharmony_ci        default:
3153d0407baSopenharmony_ci            return;
3163d0407baSopenharmony_ci    }
3173d0407baSopenharmony_ci
3183d0407baSopenharmony_ci    read_csi2_dphy_reg(hw, offset, &val);
3193d0407baSopenharmony_ci    val = (val & ~0x7f) | hsfreq;
3203d0407baSopenharmony_ci    write_csi2_dphy_reg(hw, offset, val);
3213d0407baSopenharmony_ci}
3223d0407baSopenharmony_ci
3233d0407baSopenharmony_cistatic const struct grf_reg rk3568_grf_dphy_regs[] = {
3243d0407baSopenharmony_ci    [GRF_DPHY_CSI2PHY_FORCERXMODE] = GRF_REG(GRF_VI_CON0, 4, 0),
3253d0407baSopenharmony_ci    [GRF_DPHY_CSI2PHY_DATALANE_EN] = GRF_REG(GRF_VI_CON0, 4, 4),
3263d0407baSopenharmony_ci    [GRF_DPHY_CSI2PHY_DATALANE_EN0] = GRF_REG(GRF_VI_CON0, 2, 4),
3273d0407baSopenharmony_ci    [GRF_DPHY_CSI2PHY_DATALANE_EN1] = GRF_REG(GRF_VI_CON0, 2, 6),
3283d0407baSopenharmony_ci    [GRF_DPHY_CSI2PHY_CLKLANE_EN] = GRF_REG(GRF_VI_CON0, 1, 8),
3293d0407baSopenharmony_ci    [GRF_DPHY_CLK_INV_SEL] = GRF_REG(GRF_VI_CON0, 1, 9),
3303d0407baSopenharmony_ci    [GRF_DPHY_CSI2PHY_CLKLANE1_EN] = GRF_REG(GRF_VI_CON0, 1, 10),
3313d0407baSopenharmony_ci    [GRF_DPHY_CLK1_INV_SEL] = GRF_REG(GRF_VI_CON0, 1, 11),
3323d0407baSopenharmony_ci    [GRF_DPHY_ISP_CSI2PHY_SEL] = GRF_REG(GRF_VI_CON1, 1, 12),
3333d0407baSopenharmony_ci    [GRF_DPHY_CIF_CSI2PHY_SEL] = GRF_REG(GRF_VI_CON1, 1, 11),
3343d0407baSopenharmony_ci    [GRF_DPHY_CSI2PHY_LANE_SEL] = GRF_REG(GRF_VI_CON1, 1, 7),
3353d0407baSopenharmony_ci};
3363d0407baSopenharmony_ci
3373d0407baSopenharmony_cistatic const struct csi2dphy_reg rk3568_csi2dphy_regs[] = {
3383d0407baSopenharmony_ci    [CSI2PHY_REG_CTRL_LANE_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CTRL_LANE_ENABLE),
3393d0407baSopenharmony_ci    [CSI2PHY_DUAL_CLK_EN] = CSI2PHY_REG(CSI2_DPHY_DUAL_CAL_EN),
3403d0407baSopenharmony_ci    [CSI2PHY_CLK_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_CLK_WR_THS_SETTLE),
3413d0407baSopenharmony_ci    [CSI2PHY_CLK_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK_CALIB_EN),
3423d0407baSopenharmony_ci    [CSI2PHY_LANE0_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE0_WR_THS_SETTLE),
3433d0407baSopenharmony_ci    [CSI2PHY_LANE0_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE0_CALIB_EN),
3443d0407baSopenharmony_ci    [CSI2PHY_LANE1_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE1_WR_THS_SETTLE),
3453d0407baSopenharmony_ci    [CSI2PHY_LANE1_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE1_CALIB_EN),
3463d0407baSopenharmony_ci    [CSI2PHY_LANE2_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE2_WR_THS_SETTLE),
3473d0407baSopenharmony_ci    [CSI2PHY_LANE2_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE2_CALIB_EN),
3483d0407baSopenharmony_ci    [CSI2PHY_LANE3_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE3_WR_THS_SETTLE),
3493d0407baSopenharmony_ci    [CSI2PHY_LANE3_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE3_CALIB_EN),
3503d0407baSopenharmony_ci    [CSI2PHY_CLK1_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_WR_THS_SETTLE),
3513d0407baSopenharmony_ci    [CSI2PHY_CLK1_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_CALIB_EN),
3523d0407baSopenharmony_ci};
3533d0407baSopenharmony_ci
3543d0407baSopenharmony_cistatic const struct grf_reg rk3588_grf_dphy_regs[] = {
3553d0407baSopenharmony_ci    [GRF_DPHY_CSI2PHY_FORCERXMODE] = GRF_REG(GRF_DPHY_CON0, 4, 0),
3563d0407baSopenharmony_ci    [GRF_DPHY_CSI2PHY_DATALANE_EN] = GRF_REG(GRF_DPHY_CON0, 4, 4),
3573d0407baSopenharmony_ci    [GRF_DPHY_CSI2PHY_DATALANE_EN0] = GRF_REG(GRF_DPHY_CON0, 2, 4),
3583d0407baSopenharmony_ci    [GRF_DPHY_CSI2PHY_DATALANE_EN1] = GRF_REG(GRF_DPHY_CON0, 2, 6),
3593d0407baSopenharmony_ci    [GRF_DPHY_CSI2PHY_CLKLANE_EN] = GRF_REG(GRF_DPHY_CON0, 1, 8),
3603d0407baSopenharmony_ci    [GRF_DPHY_CLK_INV_SEL] = GRF_REG(GRF_DPHY_CON0, 1, 9),
3613d0407baSopenharmony_ci    [GRF_DPHY_CSI2PHY_CLKLANE1_EN] = GRF_REG(GRF_DPHY_CON0, 1, 10),
3623d0407baSopenharmony_ci    [GRF_DPHY_CLK1_INV_SEL] = GRF_REG(GRF_DPHY_CON0, 1, 11),
3633d0407baSopenharmony_ci    [GRF_DPHY_CSI2PHY_LANE_SEL] = GRF_REG(GRF_SOC_CON2, 1, 6),
3643d0407baSopenharmony_ci    [GRF_DPHY_CSI2PHY1_LANE_SEL] = GRF_REG(GRF_SOC_CON2, 1, 7),
3653d0407baSopenharmony_ci    [GRF_DPHY_CSIHOST2_SEL] = GRF_REG(GRF_SOC_CON2, 1, 8),
3663d0407baSopenharmony_ci    [GRF_DPHY_CSIHOST3_SEL] = GRF_REG(GRF_SOC_CON2, 1, 9),
3673d0407baSopenharmony_ci    [GRF_DPHY_CSIHOST4_SEL] = GRF_REG(GRF_SOC_CON2, 1, 10),
3683d0407baSopenharmony_ci    [GRF_DPHY_CSIHOST5_SEL] = GRF_REG(GRF_SOC_CON2, 1, 11),
3693d0407baSopenharmony_ci};
3703d0407baSopenharmony_ci
3713d0407baSopenharmony_cistatic const struct csi2dphy_reg rk3588_csi2dphy_regs[] = {
3723d0407baSopenharmony_ci    [CSI2PHY_REG_CTRL_LANE_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CTRL_LANE_ENABLE),
3733d0407baSopenharmony_ci    [CSI2PHY_DUAL_CLK_EN] = CSI2PHY_REG(CSI2_DPHY_DUAL_CAL_EN),
3743d0407baSopenharmony_ci    [CSI2PHY_CLK_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_CLK_WR_THS_SETTLE),
3753d0407baSopenharmony_ci    [CSI2PHY_CLK_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK_CALIB_EN),
3763d0407baSopenharmony_ci    [CSI2PHY_LANE0_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE0_WR_THS_SETTLE),
3773d0407baSopenharmony_ci    [CSI2PHY_LANE0_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE0_CALIB_EN),
3783d0407baSopenharmony_ci    [CSI2PHY_LANE1_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE1_WR_THS_SETTLE),
3793d0407baSopenharmony_ci    [CSI2PHY_LANE1_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE1_CALIB_EN),
3803d0407baSopenharmony_ci    [CSI2PHY_LANE2_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE2_WR_THS_SETTLE),
3813d0407baSopenharmony_ci    [CSI2PHY_LANE2_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE2_CALIB_EN),
3823d0407baSopenharmony_ci    [CSI2PHY_LANE3_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE3_WR_THS_SETTLE),
3833d0407baSopenharmony_ci    [CSI2PHY_LANE3_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE3_CALIB_EN),
3843d0407baSopenharmony_ci    [CSI2PHY_CLK1_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_WR_THS_SETTLE),
3853d0407baSopenharmony_ci    [CSI2PHY_CLK1_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_CALIB_EN),
3863d0407baSopenharmony_ci    [CSI2PHY_CLK1_LANE_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_LANE_EN),
3873d0407baSopenharmony_ci};
3883d0407baSopenharmony_ci
3893d0407baSopenharmony_cistatic const struct grf_reg rk3588_grf_dcphy_regs[] = {
3903d0407baSopenharmony_ci    [GRF_CPHY_MODE] = GRF_REG(GRF_DCPHY_CON0, 9, 0),
3913d0407baSopenharmony_ci};
3923d0407baSopenharmony_ci
3933d0407baSopenharmony_cistatic const struct csi2dphy_reg rk3588_csi2dcphy_regs[] = {
3943d0407baSopenharmony_ci    [CSI2PHY_CLK_THS_SETTLE] = CSI2PHY_REG(CSI2_DCPHY_CLK_WR_THS_SETTLE),
3953d0407baSopenharmony_ci    [CSI2PHY_LANE0_THS_SETTLE] = CSI2PHY_REG(CSI2_DCPHY_LANE0_WR_THS_SETTLE),
3963d0407baSopenharmony_ci    [CSI2PHY_LANE0_ERR_SOT_SYNC] = CSI2PHY_REG(CSI2_DCPHY_LANE0_WR_ERR_SOT_SYNC),
3973d0407baSopenharmony_ci    [CSI2PHY_LANE1_THS_SETTLE] = CSI2PHY_REG(CSI2_DCPHY_LANE1_WR_THS_SETTLE),
3983d0407baSopenharmony_ci    [CSI2PHY_LANE1_ERR_SOT_SYNC] = CSI2PHY_REG(CSI2_DCPHY_LANE1_WR_ERR_SOT_SYNC),
3993d0407baSopenharmony_ci    [CSI2PHY_LANE2_THS_SETTLE] = CSI2PHY_REG(CSI2_DCPHY_LANE2_WR_THS_SETTLE),
4003d0407baSopenharmony_ci    [CSI2PHY_LANE2_ERR_SOT_SYNC] = CSI2PHY_REG(CSI2_DCPHY_LANE2_WR_ERR_SOT_SYNC),
4013d0407baSopenharmony_ci    [CSI2PHY_LANE3_THS_SETTLE] = CSI2PHY_REG(CSI2_DCPHY_LANE3_WR_THS_SETTLE),
4023d0407baSopenharmony_ci    [CSI2PHY_LANE3_ERR_SOT_SYNC] = CSI2PHY_REG(CSI2_DCPHY_LANE3_WR_ERR_SOT_SYNC),
4033d0407baSopenharmony_ci    [CSI2PHY_CLK_LANE_ENABLE] = CSI2PHY_REG(CSI2_DCPHY_CLK_LANE_ENABLE),
4043d0407baSopenharmony_ci    [CSI2PHY_DATA_LANE0_ENABLE] = CSI2PHY_REG(CSI2_DCPHY_DATA_LANE0_ENABLE),
4053d0407baSopenharmony_ci    [CSI2PHY_DATA_LANE1_ENABLE] = CSI2PHY_REG(CSI2_DCPHY_DATA_LANE1_ENABLE),
4063d0407baSopenharmony_ci    [CSI2PHY_DATA_LANE2_ENABLE] = CSI2PHY_REG(CSI2_DCPHY_DATA_LANE2_ENABLE),
4073d0407baSopenharmony_ci    [CSI2PHY_DATA_LANE3_ENABLE] = CSI2PHY_REG(CSI2_DCPHY_DATA_LANE3_ENABLE),
4083d0407baSopenharmony_ci    [CSI2PHY_S0C_GNR_CON1] = CSI2PHY_REG(CSI2_DCPHY_S0C_GNR_CON1),
4093d0407baSopenharmony_ci    [CSI2PHY_COMBO_S0D0_GNR_CON1] = CSI2PHY_REG(CSI2_DCPHY_COMBO_S0D0_GNR_CON1),
4103d0407baSopenharmony_ci    [CSI2PHY_COMBO_S0D1_GNR_CON1] = CSI2PHY_REG(CSI2_DCPHY_COMBO_S0D1_GNR_CON1),
4113d0407baSopenharmony_ci    [CSI2PHY_COMBO_S0D2_GNR_CON1] = CSI2PHY_REG(CSI2_DCPHY_COMBO_S0D2_GNR_CON1),
4123d0407baSopenharmony_ci    [CSI2PHY_S0D3_GNR_CON1] = CSI2PHY_REG(CSI2_DCPHY_S0D3_GNR_CON1),
4133d0407baSopenharmony_ci};
4143d0407baSopenharmony_ci
4153d0407baSopenharmony_ci/* These tables must be sorted by .range_h ascending. */
4163d0407baSopenharmony_cistatic const struct hsfreq_range rk3568_csi2_dphy_hw_hsfreq_ranges[] = {
4173d0407baSopenharmony_ci    {109, 0x02},  {149, 0x03},  {199, 0x06},  {249, 0x06},  {299, 0x06},  {399, 0x08},  {499, 0x0b},
4183d0407baSopenharmony_ci    {599, 0x0e},  {699, 0x10},  {799, 0x12},  {999, 0x16},  {1199, 0x1e}, {1399, 0x23}, {1599, 0x2d},
4193d0407baSopenharmony_ci    {1799, 0x32}, {1999, 0x37}, {2199, 0x3c}, {2399, 0x41}, {2499, 0x46}};
4203d0407baSopenharmony_ci
4213d0407baSopenharmony_ci/* These tables must be sorted by .range_h ascending. */
4223d0407baSopenharmony_cistatic const struct hsfreq_range rk3588_csi2_dcphy_d_hw_hsfreq_ranges[] = {
4233d0407baSopenharmony_ci    {80, 0x105},   {100, 0x106},  {120, 0x107},  {140, 0x108},  {160, 0x109},  {180, 0x10a},  {200, 0x10b},
4243d0407baSopenharmony_ci    {220, 0x10c},  {240, 0x10d},  {270, 0x10e},  {290, 0x10f},  {310, 0x110},  {330, 0x111},  {350, 0x112},
4253d0407baSopenharmony_ci    {370, 0x113},  {390, 0x114},  {410, 0x115},  {430, 0x116},  {450, 0x117},  {470, 0x118},  {490, 0x119},
4263d0407baSopenharmony_ci    {510, 0x11a},  {540, 0x11b},  {560, 0x11c},  {580, 0x11d},  {600, 0x11e},  {620, 0x11f},  {640, 0x120},
4273d0407baSopenharmony_ci    {660, 0x121},  {680, 0x122},  {700, 0x123},  {720, 0x124},  {740, 0x125},  {760, 0x126},  {790, 0x127},
4283d0407baSopenharmony_ci    {810, 0x128},  {830, 0x129},  {850, 0x12a},  {870, 0x12b},  {890, 0x12c},  {910, 0x12d},  {930, 0x12e},
4293d0407baSopenharmony_ci    {950, 0x12f},  {970, 0x130},  {990, 0x131},  {1010, 0x132}, {1030, 0x133}, {1060, 0x134}, {1080, 0x135},
4303d0407baSopenharmony_ci    {1100, 0x136}, {1120, 0x137}, {1140, 0x138}, {1160, 0x139}, {1180, 0x13a}, {1200, 0x13b}, {1220, 0x13c},
4313d0407baSopenharmony_ci    {1240, 0x13d}, {1260, 0x13e}, {1280, 0x13f}, {1310, 0x140}, {1330, 0x141}, {1350, 0x142}, {1370, 0x143},
4323d0407baSopenharmony_ci    {1390, 0x144}, {1410, 0x145}, {1430, 0x146}, {1450, 0x147}, {1470, 0x148}, {1490, 0x149}, {1580, 0x007},
4333d0407baSopenharmony_ci    {1740, 0x008}, {1910, 0x009}, {2070, 0x00a}, {2240, 0x00b}, {2410, 0x00c}, {2570, 0x00d}, {2740, 0x00e},
4343d0407baSopenharmony_ci    {2910, 0x00f}, {3070, 0x010}, {3240, 0x011}, {3410, 0x012}, {3570, 0x013}, {3740, 0x014}, {3890, 0x015},
4353d0407baSopenharmony_ci    {4070, 0x016}, {4240, 0x017}, {4400, 0x018}, {4500, 0x019},
4363d0407baSopenharmony_ci};
4373d0407baSopenharmony_ci
4383d0407baSopenharmony_ci/* These tables must be sorted by .range_h ascending. */
4393d0407baSopenharmony_cistatic const struct hsfreq_range rk3588_csi2_dcphy_c_hw_hsfreq_ranges[] = {
4403d0407baSopenharmony_ci    {500, 0x102},
4413d0407baSopenharmony_ci    {990, 0x002},
4423d0407baSopenharmony_ci    {2500, 0x001},
4433d0407baSopenharmony_ci};
4443d0407baSopenharmony_ci
4453d0407baSopenharmony_cistatic struct v4l2_subdev *get_remote_sensor(struct v4l2_subdev *sd)
4463d0407baSopenharmony_ci{
4473d0407baSopenharmony_ci    struct media_pad *local, *remote;
4483d0407baSopenharmony_ci    struct media_entity *sensor_me;
4493d0407baSopenharmony_ci
4503d0407baSopenharmony_ci    local = &sd->entity.pads[CSI2_DPHY_RX_PAD_SINK];
4513d0407baSopenharmony_ci    remote = media_entity_remote_pad(local);
4523d0407baSopenharmony_ci    if (!remote) {
4533d0407baSopenharmony_ci        v4l2_warn(sd, "No link between dphy and sensor\n");
4543d0407baSopenharmony_ci        return NULL;
4553d0407baSopenharmony_ci    }
4563d0407baSopenharmony_ci
4573d0407baSopenharmony_ci    sensor_me = media_entity_remote_pad(local)->entity;
4583d0407baSopenharmony_ci    return media_entity_to_v4l2_subdev(sensor_me);
4593d0407baSopenharmony_ci}
4603d0407baSopenharmony_ci
4613d0407baSopenharmony_cistatic struct csi2_sensor *sd_to_sensor(struct csi2_dphy *dphy, struct v4l2_subdev *sd)
4623d0407baSopenharmony_ci{
4633d0407baSopenharmony_ci    int i;
4643d0407baSopenharmony_ci
4653d0407baSopenharmony_ci    for (i = 0; i < dphy->num_sensors; ++i) {
4663d0407baSopenharmony_ci        if (dphy->sensors[i].sd == sd) {
4673d0407baSopenharmony_ci            return &dphy->sensors[i];
4683d0407baSopenharmony_ci        }
4693d0407baSopenharmony_ci    }
4703d0407baSopenharmony_ci
4713d0407baSopenharmony_ci    return NULL;
4723d0407baSopenharmony_ci}
4733d0407baSopenharmony_ci
4743d0407baSopenharmony_cistatic void csi2_dphy_hw_do_reset(struct csi2_dphy_hw *hw)
4753d0407baSopenharmony_ci{
4763d0407baSopenharmony_ci    if (hw->rsts_bulk) {
4773d0407baSopenharmony_ci        reset_control_assert(hw->rsts_bulk);
4783d0407baSopenharmony_ci    }
4793d0407baSopenharmony_ci
4803d0407baSopenharmony_ci    udelay(0X05);
4813d0407baSopenharmony_ci
4823d0407baSopenharmony_ci    if (hw->rsts_bulk) {
4833d0407baSopenharmony_ci        reset_control_deassert(hw->rsts_bulk);
4843d0407baSopenharmony_ci    }
4853d0407baSopenharmony_ci}
4863d0407baSopenharmony_ci
4873d0407baSopenharmony_cistatic void csi2_dphy_config_dual_mode(struct csi2_dphy *dphy, struct csi2_sensor *sensor)
4883d0407baSopenharmony_ci{
4893d0407baSopenharmony_ci    struct csi2_dphy_hw *hw = dphy->dphy_hw;
4903d0407baSopenharmony_ci    struct v4l2_subdev *sd = &dphy->sd;
4913d0407baSopenharmony_ci    bool is_cif = false;
4923d0407baSopenharmony_ci    char *model;
4933d0407baSopenharmony_ci    u32 val;
4943d0407baSopenharmony_ci
4953d0407baSopenharmony_ci    model = sd->v4l2_dev->mdev->model;
4963d0407baSopenharmony_ci    if (!strncmp(model, "rkcif_mipi_lvds", sizeof("rkcif_mipi_lvds") - 1)) {
4973d0407baSopenharmony_ci        is_cif = true;
4983d0407baSopenharmony_ci    } else {
4993d0407baSopenharmony_ci        is_cif = false;
5003d0407baSopenharmony_ci    }
5013d0407baSopenharmony_ci
5023d0407baSopenharmony_ci    if (hw->lane_mode == LANE_MODE_FULL) {
5033d0407baSopenharmony_ci        val = ~GRF_CSI2PHY_LANE_SEL_SPLIT;
5043d0407baSopenharmony_ci        if (dphy->phy_index < 0X03) {
5053d0407baSopenharmony_ci            write_grf_reg(hw, GRF_DPHY_CSI2PHY_DATALANE_EN, GENMASK(sensor->lanes - 1, 0));
5063d0407baSopenharmony_ci            write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE_EN, 0x1);
5073d0407baSopenharmony_ci            if (hw->drv_data->chip_id < CHIP_ID_RK3588) {
5083d0407baSopenharmony_ci                write_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val);
5093d0407baSopenharmony_ci            } else {
5103d0407baSopenharmony_ci                write_sys_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val);
5113d0407baSopenharmony_ci            }
5123d0407baSopenharmony_ci        } else {
5133d0407baSopenharmony_ci            write_grf_reg(hw, GRF_DPHY_CSI2PHY_DATALANE_EN, GENMASK(sensor->lanes - 1, 0));
5143d0407baSopenharmony_ci            write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE_EN, 0x1);
5153d0407baSopenharmony_ci            if (hw->drv_data->chip_id < CHIP_ID_RK3588) {
5163d0407baSopenharmony_ci                write_grf_reg(hw, GRF_DPHY_CSI2PHY1_LANE_SEL, val);
5173d0407baSopenharmony_ci            } else {
5183d0407baSopenharmony_ci                write_sys_grf_reg(hw, GRF_DPHY_CSI2PHY1_LANE_SEL, val);
5193d0407baSopenharmony_ci            }
5203d0407baSopenharmony_ci        }
5213d0407baSopenharmony_ci    } else {
5223d0407baSopenharmony_ci        val = GRF_CSI2PHY_LANE_SEL_SPLIT;
5233d0407baSopenharmony_ci
5243d0407baSopenharmony_ci        switch (dphy->phy_index) {
5253d0407baSopenharmony_ci            case 1:
5263d0407baSopenharmony_ci                write_grf_reg(hw, GRF_DPHY_CSI2PHY_DATALANE_EN0, GENMASK(sensor->lanes - 1, 0));
5273d0407baSopenharmony_ci                write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE_EN, 0x1);
5283d0407baSopenharmony_ci                if (hw->drv_data->chip_id < CHIP_ID_RK3588) {
5293d0407baSopenharmony_ci                    write_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val);
5303d0407baSopenharmony_ci                    if (is_cif) {
5313d0407baSopenharmony_ci                        write_grf_reg(hw, GRF_DPHY_CIF_CSI2PHY_SEL, GRF_CSI2PHY_SEL_SPLIT_0_1);
5323d0407baSopenharmony_ci                    } else {
5333d0407baSopenharmony_ci                        write_grf_reg(hw, GRF_DPHY_ISP_CSI2PHY_SEL, GRF_CSI2PHY_SEL_SPLIT_0_1);
5343d0407baSopenharmony_ci                    }
5353d0407baSopenharmony_ci                } else {
5363d0407baSopenharmony_ci                    write_sys_grf_reg(hw, GRF_DPHY_CSIHOST2_SEL, 0x0);
5373d0407baSopenharmony_ci                    write_sys_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val);
5383d0407baSopenharmony_ci                }
5393d0407baSopenharmony_ci                break;
5403d0407baSopenharmony_ci            case 0X02:
5413d0407baSopenharmony_ci                write_grf_reg(hw, GRF_DPHY_CSI2PHY_DATALANE_EN1, GENMASK(sensor->lanes - 1, 0));
5423d0407baSopenharmony_ci                write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE1_EN, 0x1);
5433d0407baSopenharmony_ci                if (hw->drv_data->chip_id < CHIP_ID_RK3588) {
5443d0407baSopenharmony_ci                    write_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val);
5453d0407baSopenharmony_ci                    if (is_cif) {
5463d0407baSopenharmony_ci                        write_grf_reg(hw, GRF_DPHY_CIF_CSI2PHY_SEL, GRF_CSI2PHY_SEL_SPLIT_2_3);
5473d0407baSopenharmony_ci                    } else {
5483d0407baSopenharmony_ci                        write_grf_reg(hw, GRF_DPHY_ISP_CSI2PHY_SEL, GRF_CSI2PHY_SEL_SPLIT_2_3);
5493d0407baSopenharmony_ci                    }
5503d0407baSopenharmony_ci                } else {
5513d0407baSopenharmony_ci                    write_sys_grf_reg(hw, GRF_DPHY_CSIHOST3_SEL, 0x1);
5523d0407baSopenharmony_ci                    write_sys_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val);
5533d0407baSopenharmony_ci                }
5543d0407baSopenharmony_ci                break;
5553d0407baSopenharmony_ci            case 0X04:
5563d0407baSopenharmony_ci                write_sys_grf_reg(hw, GRF_DPHY_CSI2PHY1_LANE_SEL, val);
5573d0407baSopenharmony_ci                write_sys_grf_reg(hw, GRF_DPHY_CSIHOST4_SEL, 0x0);
5583d0407baSopenharmony_ci                write_grf_reg(hw, GRF_DPHY_CSI2PHY_DATALANE_EN0, GENMASK(sensor->lanes - 1, 0));
5593d0407baSopenharmony_ci                write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE_EN, 0x1);
5603d0407baSopenharmony_ci                break;
5613d0407baSopenharmony_ci            case 0X05:
5623d0407baSopenharmony_ci                write_sys_grf_reg(hw, GRF_DPHY_CSI2PHY1_LANE_SEL, val);
5633d0407baSopenharmony_ci                write_sys_grf_reg(hw, GRF_DPHY_CSIHOST5_SEL, 0x1);
5643d0407baSopenharmony_ci                write_grf_reg(hw, GRF_DPHY_CSI2PHY_DATALANE_EN1, GENMASK(sensor->lanes - 1, 0));
5653d0407baSopenharmony_ci                write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE1_EN, 0x1);
5663d0407baSopenharmony_ci                break;
5673d0407baSopenharmony_ci            default:
5683d0407baSopenharmony_ci                break;
5693d0407baSopenharmony_ci        };
5703d0407baSopenharmony_ci    }
5713d0407baSopenharmony_ci}
5723d0407baSopenharmony_ci
5733d0407baSopenharmony_cistatic int csi2_dphy_hw_stream_on(struct csi2_dphy *dphy, struct v4l2_subdev *sd)
5743d0407baSopenharmony_ci{
5753d0407baSopenharmony_ci    struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
5763d0407baSopenharmony_ci    struct csi2_sensor *sensor = sd_to_sensor(dphy, sensor_sd);
5773d0407baSopenharmony_ci    struct csi2_dphy_hw *hw = dphy->dphy_hw;
5783d0407baSopenharmony_ci    const struct dphy_hw_drv_data *drv_data = hw->drv_data;
5793d0407baSopenharmony_ci    const struct hsfreq_range *hsfreq_ranges = drv_data->hsfreq_ranges;
5803d0407baSopenharmony_ci    int num_hsfreq_ranges = drv_data->num_hsfreq_ranges;
5813d0407baSopenharmony_ci    int i, hsfreq = 0;
5823d0407baSopenharmony_ci    u32 val = 0, pre_val;
5833d0407baSopenharmony_ci
5843d0407baSopenharmony_ci    mutex_lock(&hw->mutex);
5853d0407baSopenharmony_ci
5863d0407baSopenharmony_ci    /* set data lane num and enable clock lane */
5873d0407baSopenharmony_ci    /*
5883d0407baSopenharmony_ci     * for rk356x: dphy0 is used just for full mode,
5893d0407baSopenharmony_ci     *             dphy1 is used just for split mode,uses lane0_1,
5903d0407baSopenharmony_ci     *             dphy2 is used just for split mode,uses lane2_3
5913d0407baSopenharmony_ci     */
5923d0407baSopenharmony_ci    read_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, &pre_val);
5933d0407baSopenharmony_ci    if (hw->lane_mode == LANE_MODE_FULL) {
5943d0407baSopenharmony_ci        val |= (GENMASK(sensor->lanes - 1, 0) << CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT) |
5953d0407baSopenharmony_ci               (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT);
5963d0407baSopenharmony_ci    } else {
5973d0407baSopenharmony_ci        if (!(pre_val & (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT))) {
5983d0407baSopenharmony_ci            val |= (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT);
5993d0407baSopenharmony_ci        }
6003d0407baSopenharmony_ci
6013d0407baSopenharmony_ci        if (dphy->phy_index % 0X03 == DPHY1) {
6023d0407baSopenharmony_ci            val |= (GENMASK(sensor->lanes - 1, 0) << CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT);
6033d0407baSopenharmony_ci        }
6043d0407baSopenharmony_ci
6053d0407baSopenharmony_ci        if (dphy->phy_index % 0x03 == DPHY2) {
6063d0407baSopenharmony_ci            val |= (GENMASK(sensor->lanes - 1, 0) << CSI2_DPHY_CTRL_DATALANE_SPLIT_LANE2_3_OFFSET_BIT);
6073d0407baSopenharmony_ci            write_csi2_dphy_reg(hw, CSI2PHY_CLK1_LANE_ENABLE, BIT(0x06));
6083d0407baSopenharmony_ci        }
6093d0407baSopenharmony_ci    }
6103d0407baSopenharmony_ci    val |= pre_val;
6113d0407baSopenharmony_ci    write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, val);
6123d0407baSopenharmony_ci
6133d0407baSopenharmony_ci    if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) {
6143d0407baSopenharmony_ci        /* Reset dphy digital part */
6153d0407baSopenharmony_ci        if (hw->lane_mode == LANE_MODE_FULL) {
6163d0407baSopenharmony_ci            write_csi2_dphy_reg(hw, CSI2PHY_DUAL_CLK_EN, 0x1e);
6173d0407baSopenharmony_ci            write_csi2_dphy_reg(hw, CSI2PHY_DUAL_CLK_EN, 0x1f);
6183d0407baSopenharmony_ci        } else {
6193d0407baSopenharmony_ci            read_csi2_dphy_reg(hw, CSI2PHY_DUAL_CLK_EN, &val);
6203d0407baSopenharmony_ci            if (!(val & CSI2_DPHY_LANE_DUAL_MODE_EN)) {
6213d0407baSopenharmony_ci                write_csi2_dphy_reg(hw, CSI2PHY_DUAL_CLK_EN, 0x5e);
6223d0407baSopenharmony_ci                write_csi2_dphy_reg(hw, CSI2PHY_DUAL_CLK_EN, 0x5f);
6233d0407baSopenharmony_ci            }
6243d0407baSopenharmony_ci        }
6253d0407baSopenharmony_ci        csi2_dphy_config_dual_mode(dphy, sensor);
6263d0407baSopenharmony_ci    }
6273d0407baSopenharmony_ci
6283d0407baSopenharmony_ci    /* not into receive mode/wait stopstate */
6293d0407baSopenharmony_ci    write_grf_reg(hw, GRF_DPHY_CSI2PHY_FORCERXMODE, 0x0);
6303d0407baSopenharmony_ci
6313d0407baSopenharmony_ci    /* enable calibration */
6323d0407baSopenharmony_ci    if (dphy->data_rate_mbps > 0x5dc) {
6333d0407baSopenharmony_ci        if (hw->lane_mode == LANE_MODE_FULL) {
6343d0407baSopenharmony_ci            write_csi2_dphy_reg(hw, CSI2PHY_CLK_CALIB_ENABLE, 0x80);
6353d0407baSopenharmony_ci            if (sensor->lanes > 0x00) {
6363d0407baSopenharmony_ci                write_csi2_dphy_reg(hw, CSI2PHY_LANE0_CALIB_ENABLE, 0x80);
6373d0407baSopenharmony_ci            }
6383d0407baSopenharmony_ci            if (sensor->lanes > 0x01) {
6393d0407baSopenharmony_ci                write_csi2_dphy_reg(hw, CSI2PHY_LANE1_CALIB_ENABLE, 0x80);
6403d0407baSopenharmony_ci            }
6413d0407baSopenharmony_ci            if (sensor->lanes > 0x02) {
6423d0407baSopenharmony_ci                write_csi2_dphy_reg(hw, CSI2PHY_LANE2_CALIB_ENABLE, 0x80);
6433d0407baSopenharmony_ci            }
6443d0407baSopenharmony_ci            if (sensor->lanes > 0x03) {
6453d0407baSopenharmony_ci                write_csi2_dphy_reg(hw, CSI2PHY_LANE3_CALIB_ENABLE, 0x80);
6463d0407baSopenharmony_ci            }
6473d0407baSopenharmony_ci        } else {
6483d0407baSopenharmony_ci            if (dphy->phy_index % 0x03 == DPHY1) {
6493d0407baSopenharmony_ci                write_csi2_dphy_reg(hw, CSI2PHY_CLK_CALIB_ENABLE, 0x80);
6503d0407baSopenharmony_ci                if (sensor->lanes > 0x00) {
6513d0407baSopenharmony_ci                    write_csi2_dphy_reg(hw, CSI2PHY_LANE0_CALIB_ENABLE, 0x80);
6523d0407baSopenharmony_ci                }
6533d0407baSopenharmony_ci                if (sensor->lanes > 0x01) {
6543d0407baSopenharmony_ci                    write_csi2_dphy_reg(hw, CSI2PHY_LANE1_CALIB_ENABLE, 0x80);
6553d0407baSopenharmony_ci                }
6563d0407baSopenharmony_ci            }
6573d0407baSopenharmony_ci
6583d0407baSopenharmony_ci            if (dphy->phy_index % 0x03 == DPHY2) {
6593d0407baSopenharmony_ci                write_csi2_dphy_reg(hw, CSI2PHY_CLK1_CALIB_ENABLE, 0x80);
6603d0407baSopenharmony_ci                if (sensor->lanes > 0x00) {
6613d0407baSopenharmony_ci                    write_csi2_dphy_reg(hw, CSI2PHY_LANE2_CALIB_ENABLE, 0x80);
6623d0407baSopenharmony_ci                }
6633d0407baSopenharmony_ci                if (sensor->lanes > 0x01) {
6643d0407baSopenharmony_ci                    write_csi2_dphy_reg(hw, CSI2PHY_LANE3_CALIB_ENABLE, 0x80);
6653d0407baSopenharmony_ci                }
6663d0407baSopenharmony_ci            }
6673d0407baSopenharmony_ci        }
6683d0407baSopenharmony_ci    }
6693d0407baSopenharmony_ci
6703d0407baSopenharmony_ci    /* set clock lane and data lane */
6713d0407baSopenharmony_ci    for (i = 0; i < num_hsfreq_ranges; i++) {
6723d0407baSopenharmony_ci        if (hsfreq_ranges[i].range_h >= dphy->data_rate_mbps) {
6733d0407baSopenharmony_ci            hsfreq = hsfreq_ranges[i].cfg_bit;
6743d0407baSopenharmony_ci            break;
6753d0407baSopenharmony_ci        }
6763d0407baSopenharmony_ci    }
6773d0407baSopenharmony_ci
6783d0407baSopenharmony_ci    if (i == num_hsfreq_ranges) {
6793d0407baSopenharmony_ci        i = num_hsfreq_ranges - 1;
6803d0407baSopenharmony_ci        dev_warn(dphy->dev, "data rate: %lld mbps, max support %d mbps", dphy->data_rate_mbps,
6813d0407baSopenharmony_ci                 hsfreq_ranges[i].range_h + 1);
6823d0407baSopenharmony_ci        hsfreq = hsfreq_ranges[i].cfg_bit;
6833d0407baSopenharmony_ci    }
6843d0407baSopenharmony_ci
6853d0407baSopenharmony_ci    if (hw->lane_mode == LANE_MODE_FULL) {
6863d0407baSopenharmony_ci        csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_CLOCK);
6873d0407baSopenharmony_ci        if (sensor->lanes > 0x00) {
6883d0407baSopenharmony_ci            csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_DATA0);
6893d0407baSopenharmony_ci        }
6903d0407baSopenharmony_ci        if (sensor->lanes > 0x01) {
6913d0407baSopenharmony_ci            csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_DATA1);
6923d0407baSopenharmony_ci        }
6933d0407baSopenharmony_ci        if (sensor->lanes > 0x02) {
6943d0407baSopenharmony_ci            csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_DATA2);
6953d0407baSopenharmony_ci        }
6963d0407baSopenharmony_ci        if (sensor->lanes > 0x03) {
6973d0407baSopenharmony_ci            csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_DATA3);
6983d0407baSopenharmony_ci        }
6993d0407baSopenharmony_ci    } else {
7003d0407baSopenharmony_ci        if (dphy->phy_index % 0x03 == DPHY1) {
7013d0407baSopenharmony_ci            csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_CLOCK);
7023d0407baSopenharmony_ci            csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_DATA0);
7033d0407baSopenharmony_ci            csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_DATA1);
7043d0407baSopenharmony_ci        }
7053d0407baSopenharmony_ci
7063d0407baSopenharmony_ci        if (dphy->phy_index % 0x03 == DPHY2) {
7073d0407baSopenharmony_ci            csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_CLOCK1);
7083d0407baSopenharmony_ci            csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_DATA2);
7093d0407baSopenharmony_ci            csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_DATA3);
7103d0407baSopenharmony_ci        }
7113d0407baSopenharmony_ci    }
7123d0407baSopenharmony_ci
7133d0407baSopenharmony_ci    atomic_inc(&hw->stream_cnt);
7143d0407baSopenharmony_ci
7153d0407baSopenharmony_ci    mutex_unlock(&hw->mutex);
7163d0407baSopenharmony_ci
7173d0407baSopenharmony_ci    return 0;
7183d0407baSopenharmony_ci}
7193d0407baSopenharmony_ci
7203d0407baSopenharmony_cistatic int csi2_dphy_hw_stream_off(struct csi2_dphy *dphy, struct v4l2_subdev *sd)
7213d0407baSopenharmony_ci{
7223d0407baSopenharmony_ci    struct csi2_dphy_hw *hw = dphy->dphy_hw;
7233d0407baSopenharmony_ci
7243d0407baSopenharmony_ci    if (atomic_dec_return(&hw->stream_cnt)) {
7253d0407baSopenharmony_ci        return 0;
7263d0407baSopenharmony_ci    }
7273d0407baSopenharmony_ci
7283d0407baSopenharmony_ci    mutex_lock(&hw->mutex);
7293d0407baSopenharmony_ci
7303d0407baSopenharmony_ci    write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, 0x01);
7313d0407baSopenharmony_ci    csi2_dphy_hw_do_reset(hw);
7323d0407baSopenharmony_ci    usleep_range(0x1F4, 0x3E8);
7333d0407baSopenharmony_ci
7343d0407baSopenharmony_ci    mutex_unlock(&hw->mutex);
7353d0407baSopenharmony_ci
7363d0407baSopenharmony_ci    return 0;
7373d0407baSopenharmony_ci}
7383d0407baSopenharmony_ci
7393d0407baSopenharmony_cistatic int csi_dcphy_wait_lane_prepare(struct csi2_dphy_hw *hw, int index)
7403d0407baSopenharmony_ci{
7413d0407baSopenharmony_ci    int count = 0;
7423d0407baSopenharmony_ci    u32 val = 0;
7433d0407baSopenharmony_ci
7443d0407baSopenharmony_ci    read_csi2_dphy_reg(hw, index, &val);
7453d0407baSopenharmony_ci    while (!(val & BIT(1))) {
7463d0407baSopenharmony_ci        usleep_range(0x0A, 0x14);
7473d0407baSopenharmony_ci        read_csi2_dphy_reg(hw, index, &val);
7483d0407baSopenharmony_ci        count++;
7493d0407baSopenharmony_ci        if (count > 0x7D0) {
7503d0407baSopenharmony_ci            return -EINVAL;
7513d0407baSopenharmony_ci        }
7523d0407baSopenharmony_ci    }
7533d0407baSopenharmony_ci    return 0;
7543d0407baSopenharmony_ci}
7553d0407baSopenharmony_ci
7563d0407baSopenharmony_cistatic int csi2_dcphy_hw_stream_on(struct csi2_dphy *dphy, struct v4l2_subdev *sd)
7573d0407baSopenharmony_ci{
7583d0407baSopenharmony_ci    struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
7593d0407baSopenharmony_ci    struct csi2_sensor *sensor = sd_to_sensor(dphy, sensor_sd);
7603d0407baSopenharmony_ci    struct csi2_dphy_hw *hw = dphy->dphy_hw;
7613d0407baSopenharmony_ci    const struct dphy_hw_drv_data *drv_data = hw->drv_data;
7623d0407baSopenharmony_ci    const struct hsfreq_range *hsfreq_ranges = drv_data->hsfreq_ranges;
7633d0407baSopenharmony_ci    int num_hsfreq_ranges = drv_data->num_hsfreq_ranges;
7643d0407baSopenharmony_ci    int i, hsfreq = 0;
7653d0407baSopenharmony_ci    u32 sot_sync = 0;
7663d0407baSopenharmony_ci
7673d0407baSopenharmony_ci    if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) {
7683d0407baSopenharmony_ci        hsfreq_ranges = drv_data->hsfreq_ranges;
7693d0407baSopenharmony_ci        num_hsfreq_ranges = drv_data->num_hsfreq_ranges;
7703d0407baSopenharmony_ci        sot_sync = 0x03;
7713d0407baSopenharmony_ci    } else if (sensor->mbus.type == V4L2_MBUS_CSI2_CPHY) {
7723d0407baSopenharmony_ci        hsfreq_ranges = drv_data->hsfreq_ranges_cphy;
7733d0407baSopenharmony_ci        num_hsfreq_ranges = drv_data->num_hsfreq_ranges_cphy;
7743d0407baSopenharmony_ci        sot_sync = 0x32;
7753d0407baSopenharmony_ci    }
7763d0407baSopenharmony_ci
7773d0407baSopenharmony_ci    mutex_lock(&hw->mutex);
7783d0407baSopenharmony_ci    if (sensor->mbus.type == V4L2_MBUS_CSI2_CPHY) {
7793d0407baSopenharmony_ci        write_grf_reg(hw, GRF_CPHY_MODE, 0x9);
7803d0407baSopenharmony_ci    }
7813d0407baSopenharmony_ci
7823d0407baSopenharmony_ci    if (hw->rsts_bulk) {
7833d0407baSopenharmony_ci        reset_control_assert(hw->rsts_bulk);
7843d0407baSopenharmony_ci    }
7853d0407baSopenharmony_ci
7863d0407baSopenharmony_ci    /* clk settle fix to 0x301 */
7873d0407baSopenharmony_ci    if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) {
7883d0407baSopenharmony_ci        write_csi2_dphy_reg(hw, CSI2PHY_CLK_THS_SETTLE, 0x301);
7893d0407baSopenharmony_ci        write_csi2_dphy_reg(hw, CSI2PHY_S0C_GNR_CON1, 0x1450);
7903d0407baSopenharmony_ci        write_csi2_dphy_reg(hw, CSI2PHY_COMBO_S0D0_GNR_CON1, 0x1450);
7913d0407baSopenharmony_ci        write_csi2_dphy_reg(hw, CSI2PHY_COMBO_S0D1_GNR_CON1, 0x1450);
7923d0407baSopenharmony_ci        write_csi2_dphy_reg(hw, CSI2PHY_COMBO_S0D2_GNR_CON1, 0x1450);
7933d0407baSopenharmony_ci        write_csi2_dphy_reg(hw, CSI2PHY_S0D3_GNR_CON1, 0x1450);
7943d0407baSopenharmony_ci    }
7953d0407baSopenharmony_ci    /* set data lane */
7963d0407baSopenharmony_ci    for (i = 0; i < num_hsfreq_ranges; i++) {
7973d0407baSopenharmony_ci        if (hsfreq_ranges[i].range_h >= dphy->data_rate_mbps) {
7983d0407baSopenharmony_ci            hsfreq = hsfreq_ranges[i].cfg_bit;
7993d0407baSopenharmony_ci            break;
8003d0407baSopenharmony_ci        }
8013d0407baSopenharmony_ci    }
8023d0407baSopenharmony_ci
8033d0407baSopenharmony_ci    if (i == num_hsfreq_ranges) {
8043d0407baSopenharmony_ci        i = num_hsfreq_ranges - 1;
8053d0407baSopenharmony_ci        dev_warn(dphy->dev, "data rate: %lld mbps, max support %d mbps", dphy->data_rate_mbps,
8063d0407baSopenharmony_ci                 hsfreq_ranges[i].range_h + 1);
8073d0407baSopenharmony_ci        hsfreq = hsfreq_ranges[i].cfg_bit;
8083d0407baSopenharmony_ci    }
8093d0407baSopenharmony_ci    if (sensor->lanes > 0x00) {
8103d0407baSopenharmony_ci        write_csi2_dphy_reg_mask(hw, CSI2PHY_LANE0_THS_SETTLE, hsfreq, 0x1ff);
8113d0407baSopenharmony_ci        write_csi2_dphy_reg_mask(hw, CSI2PHY_LANE0_ERR_SOT_SYNC, sot_sync, 0xff);
8123d0407baSopenharmony_ci    }
8133d0407baSopenharmony_ci    if (sensor->lanes > 0x01) {
8143d0407baSopenharmony_ci        write_csi2_dphy_reg_mask(hw, CSI2PHY_LANE1_THS_SETTLE, hsfreq, 0x1ff);
8153d0407baSopenharmony_ci        write_csi2_dphy_reg_mask(hw, CSI2PHY_LANE1_ERR_SOT_SYNC, sot_sync, 0xff);
8163d0407baSopenharmony_ci    }
8173d0407baSopenharmony_ci    if (sensor->lanes > 0x02) {
8183d0407baSopenharmony_ci        write_csi2_dphy_reg_mask(hw, CSI2PHY_LANE2_THS_SETTLE, hsfreq, 0x1ff);
8193d0407baSopenharmony_ci        write_csi2_dphy_reg_mask(hw, CSI2PHY_LANE2_ERR_SOT_SYNC, sot_sync, 0xff);
8203d0407baSopenharmony_ci    }
8213d0407baSopenharmony_ci    if (sensor->lanes > 0x03) {
8223d0407baSopenharmony_ci        write_csi2_dphy_reg_mask(hw, CSI2PHY_LANE3_THS_SETTLE, hsfreq, 0x1ff);
8233d0407baSopenharmony_ci        write_csi2_dphy_reg_mask(hw, CSI2PHY_LANE3_ERR_SOT_SYNC, sot_sync, 0xff);
8243d0407baSopenharmony_ci    }
8253d0407baSopenharmony_ci
8263d0407baSopenharmony_ci    if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) {
8273d0407baSopenharmony_ci        write_csi2_dphy_reg(hw, CSI2PHY_CLK_LANE_ENABLE, BIT(0));
8283d0407baSopenharmony_ci    }
8293d0407baSopenharmony_ci
8303d0407baSopenharmony_ci    if (sensor->lanes > 0x00) {
8313d0407baSopenharmony_ci        write_csi2_dphy_reg(hw, CSI2PHY_DATA_LANE0_ENABLE, BIT(0));
8323d0407baSopenharmony_ci    }
8333d0407baSopenharmony_ci    if (sensor->lanes > 0x01) {
8343d0407baSopenharmony_ci        write_csi2_dphy_reg(hw, CSI2PHY_DATA_LANE1_ENABLE, BIT(0));
8353d0407baSopenharmony_ci    }
8363d0407baSopenharmony_ci    if (sensor->lanes > 0x02) {
8373d0407baSopenharmony_ci        write_csi2_dphy_reg(hw, CSI2PHY_DATA_LANE2_ENABLE, BIT(0));
8383d0407baSopenharmony_ci    }
8393d0407baSopenharmony_ci    if (sensor->lanes > 0x03) {
8403d0407baSopenharmony_ci        write_csi2_dphy_reg(hw, CSI2PHY_DATA_LANE3_ENABLE, BIT(0));
8413d0407baSopenharmony_ci    }
8423d0407baSopenharmony_ci
8433d0407baSopenharmony_ci    /* wait for clk lane ready */
8443d0407baSopenharmony_ci    if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) {
8453d0407baSopenharmony_ci        if (csi_dcphy_wait_lane_prepare(hw, CSI2PHY_CLK_LANE_ENABLE)) {
8463d0407baSopenharmony_ci            goto out_streamon;
8473d0407baSopenharmony_ci        }
8483d0407baSopenharmony_ci    }
8493d0407baSopenharmony_ci
8503d0407baSopenharmony_ci    /* wait for data lane ready */
8513d0407baSopenharmony_ci    if (sensor->lanes > 0) {
8523d0407baSopenharmony_ci        if (csi_dcphy_wait_lane_prepare(hw, CSI2PHY_DATA_LANE0_ENABLE)) {
8533d0407baSopenharmony_ci            goto out_streamon;
8543d0407baSopenharmony_ci        }
8553d0407baSopenharmony_ci    }
8563d0407baSopenharmony_ci    if (sensor->lanes > 1) {
8573d0407baSopenharmony_ci        if (csi_dcphy_wait_lane_prepare(hw, CSI2PHY_DATA_LANE1_ENABLE)) {
8583d0407baSopenharmony_ci            goto out_streamon;
8593d0407baSopenharmony_ci        }
8603d0407baSopenharmony_ci    }
8613d0407baSopenharmony_ci    if (sensor->lanes > 0x02) {
8623d0407baSopenharmony_ci        if (csi_dcphy_wait_lane_prepare(hw, CSI2PHY_DATA_LANE2_ENABLE)) {
8633d0407baSopenharmony_ci            goto out_streamon;
8643d0407baSopenharmony_ci        }
8653d0407baSopenharmony_ci    }
8663d0407baSopenharmony_ci    if (sensor->lanes > 0x03) {
8673d0407baSopenharmony_ci        if (csi_dcphy_wait_lane_prepare(hw, CSI2PHY_DATA_LANE3_ENABLE)) {
8683d0407baSopenharmony_ci            goto out_streamon;
8693d0407baSopenharmony_ci        }
8703d0407baSopenharmony_ci    }
8713d0407baSopenharmony_ci
8723d0407baSopenharmony_ci    if (hw->rsts_bulk) {
8733d0407baSopenharmony_ci        reset_control_deassert(hw->rsts_bulk);
8743d0407baSopenharmony_ci    }
8753d0407baSopenharmony_ci    atomic_inc(&hw->stream_cnt);
8763d0407baSopenharmony_ci
8773d0407baSopenharmony_ci    mutex_unlock(&hw->mutex);
8783d0407baSopenharmony_ci
8793d0407baSopenharmony_ci    return 0;
8803d0407baSopenharmony_ciout_streamon:
8813d0407baSopenharmony_ci    if (hw->rsts_bulk) {
8823d0407baSopenharmony_ci        reset_control_deassert(hw->rsts_bulk);
8833d0407baSopenharmony_ci    }
8843d0407baSopenharmony_ci    mutex_unlock(&hw->mutex);
8853d0407baSopenharmony_ci    dev_err(dphy->dev, "stream on error\n");
8863d0407baSopenharmony_ci    return -EINVAL;
8873d0407baSopenharmony_ci}
8883d0407baSopenharmony_ci
8893d0407baSopenharmony_cistatic int csi2_dcphy_hw_stream_off(struct csi2_dphy *dphy, struct v4l2_subdev *sd)
8903d0407baSopenharmony_ci{
8913d0407baSopenharmony_ci    struct csi2_dphy_hw *hw = dphy->dphy_hw;
8923d0407baSopenharmony_ci    struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
8933d0407baSopenharmony_ci    struct csi2_sensor *sensor = sd_to_sensor(dphy, sensor_sd);
8943d0407baSopenharmony_ci
8953d0407baSopenharmony_ci    if (atomic_dec_return(&hw->stream_cnt)) {
8963d0407baSopenharmony_ci        return 0;
8973d0407baSopenharmony_ci    }
8983d0407baSopenharmony_ci
8993d0407baSopenharmony_ci    mutex_lock(&hw->mutex);
9003d0407baSopenharmony_ci    if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) {
9013d0407baSopenharmony_ci        write_csi2_dphy_reg(hw, CSI2PHY_CLK_LANE_ENABLE, 0);
9023d0407baSopenharmony_ci    }
9033d0407baSopenharmony_ci    if (sensor->lanes > 0x00) {
9043d0407baSopenharmony_ci        write_csi2_dphy_reg(hw, CSI2PHY_DATA_LANE0_ENABLE, 0);
9053d0407baSopenharmony_ci    }
9063d0407baSopenharmony_ci    if (sensor->lanes > 0x01) {
9073d0407baSopenharmony_ci        write_csi2_dphy_reg(hw, CSI2PHY_DATA_LANE1_ENABLE, 0);
9083d0407baSopenharmony_ci    }
9093d0407baSopenharmony_ci    if (sensor->lanes > 0x02) {
9103d0407baSopenharmony_ci        write_csi2_dphy_reg(hw, CSI2PHY_DATA_LANE2_ENABLE, 0);
9113d0407baSopenharmony_ci    }
9123d0407baSopenharmony_ci    if (sensor->lanes > 0x03) {
9133d0407baSopenharmony_ci        write_csi2_dphy_reg(hw, CSI2PHY_DATA_LANE3_ENABLE, 0);
9143d0407baSopenharmony_ci    }
9153d0407baSopenharmony_ci
9163d0407baSopenharmony_ci    usleep_range(0x1F4, 0x3E8);
9173d0407baSopenharmony_ci
9183d0407baSopenharmony_ci    mutex_unlock(&hw->mutex);
9193d0407baSopenharmony_ci
9203d0407baSopenharmony_ci    return 0;
9213d0407baSopenharmony_ci}
9223d0407baSopenharmony_ci
9233d0407baSopenharmony_cistatic void rk3568_csi2_dphy_hw_individual_init(struct csi2_dphy_hw *hw)
9243d0407baSopenharmony_ci{
9253d0407baSopenharmony_ci    hw->grf_regs = rk3568_grf_dphy_regs;
9263d0407baSopenharmony_ci}
9273d0407baSopenharmony_ci
9283d0407baSopenharmony_cistatic void rk3588_csi2_dphy_hw_individual_init(struct csi2_dphy_hw *hw)
9293d0407baSopenharmony_ci{
9303d0407baSopenharmony_ci    hw->grf_regs = rk3588_grf_dphy_regs;
9313d0407baSopenharmony_ci}
9323d0407baSopenharmony_ci
9333d0407baSopenharmony_cistatic void rk3588_csi2_dcphy_hw_individual_init(struct csi2_dphy_hw *hw)
9343d0407baSopenharmony_ci{
9353d0407baSopenharmony_ci    hw->grf_regs = rk3588_grf_dcphy_regs;
9363d0407baSopenharmony_ci}
9373d0407baSopenharmony_ci
9383d0407baSopenharmony_cistatic const struct dphy_hw_drv_data rk3568_csi2_dphy_hw_drv_data = {
9393d0407baSopenharmony_ci    .hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges,
9403d0407baSopenharmony_ci    .num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges),
9413d0407baSopenharmony_ci    .csi2dphy_regs = rk3568_csi2dphy_regs,
9423d0407baSopenharmony_ci    .grf_regs = rk3568_grf_dphy_regs,
9433d0407baSopenharmony_ci    .individual_init = rk3568_csi2_dphy_hw_individual_init,
9443d0407baSopenharmony_ci    .chip_id = CHIP_ID_RK3568,
9453d0407baSopenharmony_ci    .stream_on = csi2_dphy_hw_stream_on,
9463d0407baSopenharmony_ci    .stream_off = csi2_dphy_hw_stream_off,
9473d0407baSopenharmony_ci};
9483d0407baSopenharmony_ci
9493d0407baSopenharmony_cistatic const struct dphy_hw_drv_data rk3588_csi2_dphy_hw_drv_data = {
9503d0407baSopenharmony_ci    .hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges,
9513d0407baSopenharmony_ci    .num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges),
9523d0407baSopenharmony_ci    .csi2dphy_regs = rk3588_csi2dphy_regs,
9533d0407baSopenharmony_ci    .grf_regs = rk3588_grf_dphy_regs,
9543d0407baSopenharmony_ci    .individual_init = rk3588_csi2_dphy_hw_individual_init,
9553d0407baSopenharmony_ci    .chip_id = CHIP_ID_RK3588,
9563d0407baSopenharmony_ci    .stream_on = csi2_dphy_hw_stream_on,
9573d0407baSopenharmony_ci    .stream_off = csi2_dphy_hw_stream_off,
9583d0407baSopenharmony_ci};
9593d0407baSopenharmony_ci
9603d0407baSopenharmony_cistatic const struct dphy_hw_drv_data rk3588_csi2_dcphy_hw_drv_data = {
9613d0407baSopenharmony_ci    .hsfreq_ranges = rk3588_csi2_dcphy_d_hw_hsfreq_ranges,
9623d0407baSopenharmony_ci    .num_hsfreq_ranges = ARRAY_SIZE(rk3588_csi2_dcphy_d_hw_hsfreq_ranges),
9633d0407baSopenharmony_ci    .hsfreq_ranges_cphy = rk3588_csi2_dcphy_c_hw_hsfreq_ranges,
9643d0407baSopenharmony_ci    .num_hsfreq_ranges_cphy = ARRAY_SIZE(rk3588_csi2_dcphy_c_hw_hsfreq_ranges),
9653d0407baSopenharmony_ci    .csi2dphy_regs = rk3588_csi2dcphy_regs,
9663d0407baSopenharmony_ci    .grf_regs = rk3588_grf_dcphy_regs,
9673d0407baSopenharmony_ci    .individual_init = rk3588_csi2_dcphy_hw_individual_init,
9683d0407baSopenharmony_ci    .chip_id = CHIP_ID_RK3588_DCPHY,
9693d0407baSopenharmony_ci    .stream_on = csi2_dcphy_hw_stream_on,
9703d0407baSopenharmony_ci    .stream_off = csi2_dcphy_hw_stream_off,
9713d0407baSopenharmony_ci};
9723d0407baSopenharmony_ci
9733d0407baSopenharmony_cistatic const struct of_device_id rockchip_csi2_dphy_hw_match_id[] = {{
9743d0407baSopenharmony_ci    .compatible = "rockchip,rk3568-csi2-dphy-hw",
9753d0407baSopenharmony_ci    .data = &rk3568_csi2_dphy_hw_drv_data,
9763d0407baSopenharmony_ci}, {
9773d0407baSopenharmony_ci    .compatible = "rockchip,rk3588-csi2-dphy-hw",
9783d0407baSopenharmony_ci    .data = &rk3588_csi2_dphy_hw_drv_data,
9793d0407baSopenharmony_ci}, {
9803d0407baSopenharmony_ci    .compatible = "rockchip,rk3588-csi2-dcphy-hw",
9813d0407baSopenharmony_ci    .data = &rk3588_csi2_dcphy_hw_drv_data,
9823d0407baSopenharmony_ci}, {
9833d0407baSopenharmony_ci}};
9843d0407baSopenharmony_ciMODULE_DEVICE_TABLE(of, rockchip_csi2_dphy_hw_match_id);
9853d0407baSopenharmony_ci
9863d0407baSopenharmony_cistatic int rockchip_csi2_dphy_hw_probe(struct platform_device *pdev)
9873d0407baSopenharmony_ci{
9883d0407baSopenharmony_ci    struct device *dev = &pdev->dev;
9893d0407baSopenharmony_ci    struct csi2_dphy_hw *dphy_hw;
9903d0407baSopenharmony_ci    struct regmap *grf;
9913d0407baSopenharmony_ci    struct resource *res;
9923d0407baSopenharmony_ci    const struct of_device_id *of_id;
9933d0407baSopenharmony_ci    const struct dphy_hw_drv_data *drv_data;
9943d0407baSopenharmony_ci
9953d0407baSopenharmony_ci    dphy_hw = devm_kzalloc(dev, sizeof(*dphy_hw), GFP_KERNEL);
9963d0407baSopenharmony_ci    if (!dphy_hw) {
9973d0407baSopenharmony_ci        return -ENOMEM;
9983d0407baSopenharmony_ci    }
9993d0407baSopenharmony_ci    dphy_hw->dev = dev;
10003d0407baSopenharmony_ci
10013d0407baSopenharmony_ci    of_id = of_match_device(rockchip_csi2_dphy_hw_match_id, dev);
10023d0407baSopenharmony_ci    if (!of_id) {
10033d0407baSopenharmony_ci        return -EINVAL;
10043d0407baSopenharmony_ci    }
10053d0407baSopenharmony_ci
10063d0407baSopenharmony_ci    drv_data = of_id->data;
10073d0407baSopenharmony_ci
10083d0407baSopenharmony_ci    grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
10093d0407baSopenharmony_ci    if (IS_ERR(grf)) {
10103d0407baSopenharmony_ci        dev_err(dev, "Can't find GRF syscon\n");
10113d0407baSopenharmony_ci        return -ENODEV;
10123d0407baSopenharmony_ci    }
10133d0407baSopenharmony_ci    dphy_hw->regmap_grf = grf;
10143d0407baSopenharmony_ci
10153d0407baSopenharmony_ci    if (drv_data->chip_id == CHIP_ID_RK3588) {
10163d0407baSopenharmony_ci        grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,sys_grf");
10173d0407baSopenharmony_ci        if (IS_ERR(grf)) {
10183d0407baSopenharmony_ci            dev_err(dev, "Can't find SYS GRF syscon\n");
10193d0407baSopenharmony_ci            return -ENODEV;
10203d0407baSopenharmony_ci        }
10213d0407baSopenharmony_ci        dphy_hw->regmap_sys_grf = grf;
10223d0407baSopenharmony_ci    }
10233d0407baSopenharmony_ci
10243d0407baSopenharmony_ci    dphy_hw->num_clks = devm_clk_bulk_get_all(dev, &dphy_hw->clks_bulk);
10253d0407baSopenharmony_ci    if (dphy_hw->num_clks < 0) {
10263d0407baSopenharmony_ci        dev_err(dev, "failed to get csi2 clks\n");
10273d0407baSopenharmony_ci    }
10283d0407baSopenharmony_ci
10293d0407baSopenharmony_ci    dphy_hw->rsts_bulk = devm_reset_control_array_get_optional_exclusive(dev);
10303d0407baSopenharmony_ci    if (IS_ERR(dphy_hw->rsts_bulk)) {
10313d0407baSopenharmony_ci        dev_err_probe(dev, PTR_ERR(dphy_hw->rsts_bulk), "failed to get dphy reset\n");
10323d0407baSopenharmony_ci    }
10333d0407baSopenharmony_ci
10343d0407baSopenharmony_ci    dphy_hw->dphy_dev_num = 0;
10353d0407baSopenharmony_ci    dphy_hw->drv_data = drv_data;
10363d0407baSopenharmony_ci    dphy_hw->lane_mode = LANE_MODE_UNDEF;
10373d0407baSopenharmony_ci    dphy_hw->grf_regs = drv_data->grf_regs;
10383d0407baSopenharmony_ci    dphy_hw->txrx_regs = drv_data->txrx_regs;
10393d0407baSopenharmony_ci    dphy_hw->csi2dphy_regs = drv_data->csi2dphy_regs;
10403d0407baSopenharmony_ci
10413d0407baSopenharmony_ci    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
10423d0407baSopenharmony_ci    dphy_hw->hw_base_addr = devm_ioremap_resource(dev, res);
10433d0407baSopenharmony_ci    if (IS_ERR(dphy_hw->hw_base_addr)) {
10443d0407baSopenharmony_ci        resource_size_t offset = res->start;
10453d0407baSopenharmony_ci        resource_size_t size = resource_size(res);
10463d0407baSopenharmony_ci
10473d0407baSopenharmony_ci        dphy_hw->hw_base_addr = devm_ioremap(dev, offset, size);
10483d0407baSopenharmony_ci        if (IS_ERR(dphy_hw->hw_base_addr)) {
10493d0407baSopenharmony_ci            dev_err(dev, "Can't find csi2 dphy hw addr!\n");
10503d0407baSopenharmony_ci            return -ENODEV;
10513d0407baSopenharmony_ci        }
10523d0407baSopenharmony_ci    }
10533d0407baSopenharmony_ci    dphy_hw->stream_on = drv_data->stream_on;
10543d0407baSopenharmony_ci    dphy_hw->stream_off = drv_data->stream_off;
10553d0407baSopenharmony_ci
10563d0407baSopenharmony_ci    atomic_set(&dphy_hw->stream_cnt, 0);
10573d0407baSopenharmony_ci
10583d0407baSopenharmony_ci    mutex_init(&dphy_hw->mutex);
10593d0407baSopenharmony_ci
10603d0407baSopenharmony_ci    platform_set_drvdata(pdev, dphy_hw);
10613d0407baSopenharmony_ci
10623d0407baSopenharmony_ci    pm_runtime_enable(&pdev->dev);
10633d0407baSopenharmony_ci
10643d0407baSopenharmony_ci    dev_info(dev, "csi2 dphy hw probe successfully!\n");
10653d0407baSopenharmony_ci
10663d0407baSopenharmony_ci    return 0;
10673d0407baSopenharmony_ci}
10683d0407baSopenharmony_ci
10693d0407baSopenharmony_cistatic int rockchip_csi2_dphy_hw_remove(struct platform_device *pdev)
10703d0407baSopenharmony_ci{
10713d0407baSopenharmony_ci    struct csi2_dphy_hw *hw = platform_get_drvdata(pdev);
10723d0407baSopenharmony_ci
10733d0407baSopenharmony_ci    pm_runtime_disable(&pdev->dev);
10743d0407baSopenharmony_ci    mutex_destroy(&hw->mutex);
10753d0407baSopenharmony_ci
10763d0407baSopenharmony_ci    return 0;
10773d0407baSopenharmony_ci}
10783d0407baSopenharmony_ci
10793d0407baSopenharmony_cistatic struct platform_driver rockchip_csi2_dphy_hw_driver = {
10803d0407baSopenharmony_ci    .probe = rockchip_csi2_dphy_hw_probe,
10813d0407baSopenharmony_ci    .remove = rockchip_csi2_dphy_hw_remove,
10823d0407baSopenharmony_ci    .driver =
10833d0407baSopenharmony_ci        {
10843d0407baSopenharmony_ci            .name = "rockchip-csi2-dphy-hw",
10853d0407baSopenharmony_ci            .of_match_table = rockchip_csi2_dphy_hw_match_id,
10863d0407baSopenharmony_ci        },
10873d0407baSopenharmony_ci};
10883d0407baSopenharmony_cimodule_platform_driver(rockchip_csi2_dphy_hw_driver);
10893d0407baSopenharmony_ci
10903d0407baSopenharmony_ciMODULE_AUTHOR("Rockchip Camera/ISP team");
10913d0407baSopenharmony_ciMODULE_DESCRIPTION("Rockchip MIPI CSI2 DPHY HW driver");
10923d0407baSopenharmony_ciMODULE_LICENSE("GPL v2");
1093