Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Rockchip MIPI Synopsys DPHY RX0 driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2019 Collabora, Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Based on:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * drivers/media/platform/rockchip/isp1/mipi_dphy_sy.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * in https://chromium.googlesource.com/chromiumos/third_party/kernel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * chromeos-4.4 branch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *   Jacob Chen <jacob2.chen@rock-chips.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *   Shunqian Zheng <zhengsq@rock-chips.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/phy/phy-mipi-dphy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define RK3399_GRF_SOC_CON9		0x6224
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define RK3399_GRF_SOC_CON21		0x6254
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define RK3399_GRF_SOC_CON22		0x6258
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define RK3399_GRF_SOC_CON23		0x625c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define RK3399_GRF_SOC_CON24		0x6260
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define RK3399_GRF_SOC_CON25		0x6264
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define RK3399_GRF_SOC_STATUS1		0xe2a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define CLOCK_LANE_HS_RX_CONTROL	0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define LANE0_HS_RX_CONTROL		0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define LANE1_HS_RX_CONTROL		0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define LANE2_HS_RX_CONTROL		0x84
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define LANE3_HS_RX_CONTROL		0x94
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define LANES_THS_SETTLE_CONTROL	0x75
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define THS_SETTLE_COUNTER_THRESHOLD	0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) struct hsfreq_range {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	u16 range_h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	u8 cfg_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) static const struct hsfreq_range rk3399_mipidphy_hsfreq_ranges[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	{   89, 0x00 }, {   99, 0x10 }, {  109, 0x20 }, {  129, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	{  139, 0x11 }, {  149, 0x21 }, {  169, 0x02 }, {  179, 0x12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	{  199, 0x22 }, {  219, 0x03 }, {  239, 0x13 }, {  249, 0x23 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	{  269, 0x04 }, {  299, 0x14 }, {  329, 0x05 }, {  359, 0x15 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	{  399, 0x25 }, {  449, 0x06 }, {  499, 0x16 }, {  549, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	{  599, 0x17 }, {  649, 0x08 }, {  699, 0x18 }, {  749, 0x09 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	{  799, 0x19 }, {  849, 0x29 }, {  899, 0x39 }, {  949, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	{  999, 0x1a }, { 1049, 0x2a }, { 1099, 0x3a }, { 1149, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	{ 1199, 0x1b }, { 1249, 0x2b }, { 1299, 0x3b }, { 1349, 0x0c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	{ 1399, 0x1c }, { 1449, 0x2c }, { 1500, 0x3c }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) static const char * const rk3399_mipidphy_clks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	"dphy-ref",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	"dphy-cfg",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	"grf",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) enum dphy_reg_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	GRF_DPHY_RX0_TURNDISABLE = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	GRF_DPHY_RX0_FORCERXMODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	GRF_DPHY_RX0_FORCETXSTOPMODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	GRF_DPHY_RX0_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	GRF_DPHY_RX0_TESTCLR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	GRF_DPHY_RX0_TESTCLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	GRF_DPHY_RX0_TESTEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	GRF_DPHY_RX0_TESTDIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	GRF_DPHY_RX0_TURNREQUEST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	GRF_DPHY_RX0_TESTDOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	GRF_DPHY_TX0_TURNDISABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	GRF_DPHY_TX0_FORCERXMODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	GRF_DPHY_TX0_FORCETXSTOPMODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	GRF_DPHY_TX0_TURNREQUEST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	GRF_DPHY_TX1RX1_TURNDISABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	GRF_DPHY_TX1RX1_FORCERXMODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	GRF_DPHY_TX1RX1_FORCETXSTOPMODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	GRF_DPHY_TX1RX1_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	GRF_DPHY_TX1RX1_MASTERSLAVEZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	GRF_DPHY_TX1RX1_BASEDIR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	GRF_DPHY_TX1RX1_ENABLECLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	GRF_DPHY_TX1RX1_TURNREQUEST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	GRF_DPHY_RX1_SRC_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	/* rk3288 only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	GRF_CON_DISABLE_ISP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	GRF_CON_ISP_DPHY_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	GRF_DSI_CSI_TESTBUS_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	GRF_DVP_V18SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	/* below is for rk3399 only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	GRF_DPHY_RX0_CLK_INV_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	GRF_DPHY_RX1_CLK_INV_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct dphy_reg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	u16 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	u8 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	u8 shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define PHY_REG(_offset, _width, _shift) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	{ .offset = _offset, .mask = BIT(_width) - 1, .shift = _shift, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static const struct dphy_reg rk3399_grf_dphy_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	[GRF_DPHY_RX0_TURNREQUEST] = PHY_REG(RK3399_GRF_SOC_CON9, 4, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	[GRF_DPHY_RX0_CLK_INV_SEL] = PHY_REG(RK3399_GRF_SOC_CON9, 1, 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	[GRF_DPHY_RX1_CLK_INV_SEL] = PHY_REG(RK3399_GRF_SOC_CON9, 1, 11),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	[GRF_DPHY_RX0_ENABLE] = PHY_REG(RK3399_GRF_SOC_CON21, 4, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	[GRF_DPHY_RX0_FORCERXMODE] = PHY_REG(RK3399_GRF_SOC_CON21, 4, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	[GRF_DPHY_RX0_FORCETXSTOPMODE] = PHY_REG(RK3399_GRF_SOC_CON21, 4, 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	[GRF_DPHY_RX0_TURNDISABLE] = PHY_REG(RK3399_GRF_SOC_CON21, 4, 12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	[GRF_DPHY_TX0_FORCERXMODE] = PHY_REG(RK3399_GRF_SOC_CON22, 4, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	[GRF_DPHY_TX0_FORCETXSTOPMODE] = PHY_REG(RK3399_GRF_SOC_CON22, 4, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	[GRF_DPHY_TX0_TURNDISABLE] = PHY_REG(RK3399_GRF_SOC_CON22, 4, 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	[GRF_DPHY_TX0_TURNREQUEST] = PHY_REG(RK3399_GRF_SOC_CON22, 4, 12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	[GRF_DPHY_TX1RX1_ENABLE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	[GRF_DPHY_TX1RX1_FORCERXMODE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	[GRF_DPHY_TX1RX1_FORCETXSTOPMODE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	[GRF_DPHY_TX1RX1_TURNDISABLE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	[GRF_DPHY_TX1RX1_TURNREQUEST] = PHY_REG(RK3399_GRF_SOC_CON24, 4, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	[GRF_DPHY_RX1_SRC_SEL] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	[GRF_DPHY_TX1RX1_BASEDIR] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	[GRF_DPHY_TX1RX1_ENABLECLK] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	[GRF_DPHY_TX1RX1_MASTERSLAVEZ] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	[GRF_DPHY_RX0_TESTDIN] = PHY_REG(RK3399_GRF_SOC_CON25, 8, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	[GRF_DPHY_RX0_TESTEN] = PHY_REG(RK3399_GRF_SOC_CON25, 1, 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	[GRF_DPHY_RX0_TESTCLK] = PHY_REG(RK3399_GRF_SOC_CON25, 1, 9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	[GRF_DPHY_RX0_TESTCLR] = PHY_REG(RK3399_GRF_SOC_CON25, 1, 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	[GRF_DPHY_RX0_TESTDOUT] = PHY_REG(RK3399_GRF_SOC_STATUS1, 8, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct rk_dphy_drv_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	const char * const *clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	unsigned int num_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	const struct hsfreq_range *hsfreq_ranges;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	unsigned int num_hsfreq_ranges;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	const struct dphy_reg *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct rk_dphy {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	struct regmap *grf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	struct clk_bulk_data *clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	const struct rk_dphy_drv_data *drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	struct phy_configure_opts_mipi_dphy config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	u8 hsfreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static inline void rk_dphy_write_grf(struct rk_dphy *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 				     unsigned int index, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	const struct dphy_reg *reg = &priv->drv_data->regs[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	/* Update high word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	unsigned int val = (value << reg->shift) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			   (reg->mask << (reg->shift + 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	if (WARN_ON(!reg->offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	regmap_write(priv->grf, reg->offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static void rk_dphy_write(struct rk_dphy *priv, u8 test_code, u8 test_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTDIN, test_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTEN, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	 * With the falling edge on TESTCLK, the TESTDIN[7:0] signal content
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	 * is latched internally as the current test code. Test data is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	 * programmed internally by rising edge on TESTCLK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	 * This code assumes that TESTCLK is already 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTCLK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTEN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTDIN, test_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTCLK, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static void rk_dphy_enable(struct rk_dphy *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_FORCERXMODE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_FORCETXSTOPMODE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	/* Disable lane turn around, which is ignored in receive mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TURNREQUEST, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TURNDISABLE, 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 			  GENMASK(priv->config.lanes - 1, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	/* dphy start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTCLK, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTCLR, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	usleep_range(100, 150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTCLR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	usleep_range(100, 150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	/* set clock lane */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	/* HS hsfreq_range & lane 0  settle bypass */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	rk_dphy_write(priv, CLOCK_LANE_HS_RX_CONTROL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	/* HS RX Control of lane0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	rk_dphy_write(priv, LANE0_HS_RX_CONTROL, priv->hsfreq << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	/* HS RX Control of lane1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	rk_dphy_write(priv, LANE1_HS_RX_CONTROL, priv->hsfreq << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	/* HS RX Control of lane2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	rk_dphy_write(priv, LANE2_HS_RX_CONTROL, priv->hsfreq << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	/* HS RX Control of lane3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	rk_dphy_write(priv, LANE3_HS_RX_CONTROL, priv->hsfreq << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	/* HS RX Data Lanes Settle State Time Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	rk_dphy_write(priv, LANES_THS_SETTLE_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		      THS_SETTLE_COUNTER_THRESHOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	/* Normal operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	rk_dphy_write(priv, 0x0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static int rk_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	struct rk_dphy *priv = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	const struct rk_dphy_drv_data *drv_data = priv->drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	struct phy_configure_opts_mipi_dphy *config = &opts->mipi_dphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	unsigned int hsfreq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	u64 data_rate_mbps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	/* pass with phy_mipi_dphy_get_default_config (with pixel rate?) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	ret = phy_mipi_dphy_config_validate(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	data_rate_mbps = div_u64(config->hs_clk_rate, 1000 * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	dev_dbg(priv->dev, "lanes %d - data_rate_mbps %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		config->lanes, data_rate_mbps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	for (i = 0; i < drv_data->num_hsfreq_ranges; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		if (drv_data->hsfreq_ranges[i].range_h >= data_rate_mbps) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 			hsfreq = drv_data->hsfreq_ranges[i].cfg_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	if (!hsfreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	priv->hsfreq = hsfreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	priv->config = *config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static int rk_dphy_power_on(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	struct rk_dphy *priv = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	ret = clk_bulk_enable(priv->drv_data->num_clks, priv->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	rk_dphy_enable(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static int rk_dphy_power_off(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	struct rk_dphy *priv = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_ENABLE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	clk_bulk_disable(priv->drv_data->num_clks, priv->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static int rk_dphy_init(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	struct rk_dphy *priv = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	return clk_bulk_prepare(priv->drv_data->num_clks, priv->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static int rk_dphy_exit(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	struct rk_dphy *priv = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	clk_bulk_unprepare(priv->drv_data->num_clks, priv->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static const struct phy_ops rk_dphy_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	.power_on	= rk_dphy_power_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	.power_off	= rk_dphy_power_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	.init		= rk_dphy_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	.exit		= rk_dphy_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	.configure	= rk_dphy_configure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	.owner		= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static const struct rk_dphy_drv_data rk3399_mipidphy_drv_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	.clks = rk3399_mipidphy_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	.num_clks = ARRAY_SIZE(rk3399_mipidphy_clks),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	.hsfreq_ranges = rk3399_mipidphy_hsfreq_ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	.num_hsfreq_ranges = ARRAY_SIZE(rk3399_mipidphy_hsfreq_ranges),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	.regs = rk3399_grf_dphy_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static const struct of_device_id rk_dphy_dt_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		.compatible = "rockchip,rk3399-mipi-dphy-rx0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		.data = &rk3399_mipidphy_drv_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	{}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) MODULE_DEVICE_TABLE(of, rk_dphy_dt_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static int rk_dphy_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	const struct rk_dphy_drv_data *drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	struct phy_provider *phy_provider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	const struct of_device_id *of_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	struct rk_dphy *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	struct phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	if (!dev->parent || !dev->parent->of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	priv->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	priv->grf = syscon_node_to_regmap(dev->parent->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	if (IS_ERR(priv->grf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		dev_err(dev, "Can't find GRF syscon\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	of_id = of_match_device(rk_dphy_dt_ids, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	if (!of_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	drv_data = of_id->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	priv->drv_data = drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	priv->clks = devm_kcalloc(&pdev->dev, drv_data->num_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 				  sizeof(*priv->clks), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	if (!priv->clks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	for (i = 0; i < drv_data->num_clks; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		priv->clks[i].id = drv_data->clks[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	ret = devm_clk_bulk_get(&pdev->dev, drv_data->num_clks, priv->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	phy = devm_phy_create(dev, np, &rk_dphy_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	if (IS_ERR(phy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		dev_err(dev, "failed to create phy\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		return PTR_ERR(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	phy_set_drvdata(phy, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	return PTR_ERR_OR_ZERO(phy_provider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static struct platform_driver rk_dphy_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	.probe = rk_dphy_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		.name	= "rockchip-mipi-dphy-rx0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		.of_match_table = rk_dphy_dt_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) module_platform_driver(rk_dphy_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) MODULE_AUTHOR("Ezequiel Garcia <ezequiel@collabora.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) MODULE_DESCRIPTION("Rockchip MIPI Synopsys DPHY RX0 driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) MODULE_LICENSE("Dual MIT/GPL");