1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
6 #include <linux/bitfield.h>
7 #include <linux/bitops.h>
9 #include <linux/iopoll.h>
10 #include <linux/mod_devicetable.h>
11 #include <linux/module.h>
12 #include <linux/phy/phy.h>
13 #include <linux/phy/phy-mipi-dphy.h>
14 #include <linux/platform_device.h>
15 #include <linux/sys_soc.h>
17 #define DPHY_PMA_CMN(reg) (reg)
18 #define DPHY_PCS(reg) (0xb00 + (reg))
19 #define DPHY_ISO(reg) (0xc00 + (reg))
20 #define DPHY_WRAP(reg) (0x1000 + (reg))
22 #define DPHY_CMN_SSM DPHY_PMA_CMN(0x20)
23 #define DPHY_CMN_RX_MODE_EN BIT(10)
24 #define DPHY_CMN_RX_BANDGAP_TIMER_MASK GENMASK(8, 1)
25 #define DPHY_CMN_SSM_EN BIT(0)
27 #define DPHY_CMN_RX_BANDGAP_TIMER 0x14
29 #define DPHY_BAND_CFG DPHY_PCS(0x0)
30 #define DPHY_BAND_CFG_RIGHT_BAND GENMASK(9, 5)
31 #define DPHY_BAND_CFG_LEFT_BAND GENMASK(4, 0)
33 #define DPHY_POWER_ISLAND_EN_DATA DPHY_PCS(0x8)
34 #define DPHY_POWER_ISLAND_EN_DATA_VAL 0xaaaaaaaa
36 #define DPHY_POWER_ISLAND_EN_CLK DPHY_PCS(0xc)
37 #define DPHY_POWER_ISLAND_EN_CLK_VAL 0xaa
39 #define DPHY_LANE DPHY_WRAP(0x0)
40 #define DPHY_LANE_RESET_CMN_EN BIT(23)
42 #define DPHY_ISO_CL_CTRL_L DPHY_ISO(0x10)
43 #define DPHY_ISO_DL_CTRL_L0 DPHY_ISO(0x14)
44 #define DPHY_ISO_DL_CTRL_L1 DPHY_ISO(0x20)
45 #define DPHY_ISO_DL_CTRL_L2 DPHY_ISO(0x30)
46 #define DPHY_ISO_DL_CTRL_L3 DPHY_ISO(0x3c)
48 #define DPHY_ISO_LANE_READY_BIT 0
49 #define DPHY_ISO_LANE_READY_TIMEOUT_MS 100UL
51 #define DPHY_LANES_MIN 1
52 #define DPHY_LANES_MAX 4
60 struct cdns_dphy_rx_band
{
61 /* Rates are in Mbps. */
62 unsigned int min_rate
;
63 unsigned int max_rate
;
66 struct cdns_dphy_soc_data
{
70 /* Order of bands is important since the index is the band number. */
71 static const struct cdns_dphy_rx_band bands
[] = {
72 { 80, 100 }, { 100, 120 }, { 120, 160 }, { 160, 200 }, { 200, 240 },
73 { 240, 280 }, { 280, 320 }, { 320, 360 }, { 360, 400 }, { 400, 480 },
74 { 480, 560 }, { 560, 640 }, { 640, 720 }, { 720, 800 }, { 800, 880 },
75 { 880, 1040 }, { 1040, 1200 }, { 1200, 1350 }, { 1350, 1500 },
76 { 1500, 1750 }, { 1750, 2000 }, { 2000, 2250 }, { 2250, 2500 }
79 static int cdns_dphy_rx_power_on(struct phy
*phy
)
81 struct cdns_dphy_rx
*dphy
= phy_get_drvdata(phy
);
83 /* Start RX state machine. */
84 writel(DPHY_CMN_SSM_EN
| DPHY_CMN_RX_MODE_EN
|
85 FIELD_PREP(DPHY_CMN_RX_BANDGAP_TIMER_MASK
,
86 DPHY_CMN_RX_BANDGAP_TIMER
),
87 dphy
->regs
+ DPHY_CMN_SSM
);
92 static int cdns_dphy_rx_power_off(struct phy
*phy
)
94 struct cdns_dphy_rx
*dphy
= phy_get_drvdata(phy
);
96 writel(0, dphy
->regs
+ DPHY_CMN_SSM
);
101 static int cdns_dphy_rx_get_band_ctrl(unsigned long hs_clk_rate
)
103 unsigned int rate
, i
;
105 rate
= hs_clk_rate
/ 1000000UL;
106 /* Since CSI-2 clock is DDR, the bit rate is twice the clock rate. */
109 if (rate
< bands
[0].min_rate
)
112 for (i
= 0; i
< ARRAY_SIZE(bands
); i
++)
113 if (rate
< bands
[i
].max_rate
)
119 static inline int cdns_dphy_rx_wait_for_bit(void __iomem
*addr
,
124 return readl_relaxed_poll_timeout(addr
, val
, val
& BIT(bit
), 10,
125 DPHY_ISO_LANE_READY_TIMEOUT_MS
* 1000);
128 static int cdns_dphy_rx_wait_lane_ready(struct cdns_dphy_rx
*dphy
,
131 static const u32 data_lane_ctrl
[] = {DPHY_ISO_DL_CTRL_L0
,
134 DPHY_ISO_DL_CTRL_L3
};
135 void __iomem
*reg
= dphy
->regs
;
140 ret
= cdns_dphy_rx_wait_for_bit(reg
+ DPHY_ISO_CL_CTRL_L
,
141 DPHY_ISO_LANE_READY_BIT
);
145 for (i
= 0; i
< lanes
; i
++) {
146 ret
= cdns_dphy_rx_wait_for_bit(reg
+ data_lane_ctrl
[i
],
147 DPHY_ISO_LANE_READY_BIT
);
155 static struct cdns_dphy_soc_data j721e_soc_data
= {
156 .has_hw_cmn_rstb
= true,
159 static const struct soc_device_attribute cdns_dphy_socinfo
[] = {
163 .data
= &j721e_soc_data
,
168 static int cdns_dphy_rx_configure(struct phy
*phy
,
169 union phy_configure_opts
*opts
)
171 struct cdns_dphy_rx
*dphy
= phy_get_drvdata(phy
);
172 unsigned int reg
, lanes
= opts
->mipi_dphy
.lanes
;
173 const struct cdns_dphy_soc_data
*soc_data
= NULL
;
174 const struct soc_device_attribute
*soc
;
177 soc
= soc_device_match(cdns_dphy_socinfo
);
178 if (soc
&& soc
->data
)
179 soc_data
= soc
->data
;
180 if (!soc
|| (soc_data
&& !soc_data
->has_hw_cmn_rstb
)) {
181 reg
= DPHY_LANE_RESET_CMN_EN
;
182 writel(reg
, dphy
->regs
+ DPHY_LANE
);
185 /* Data lanes. Minimum one lane is mandatory. */
186 if (lanes
< DPHY_LANES_MIN
|| lanes
> DPHY_LANES_MAX
)
189 band_ctrl
= cdns_dphy_rx_get_band_ctrl(opts
->mipi_dphy
.hs_clk_rate
);
193 reg
= FIELD_PREP(DPHY_BAND_CFG_LEFT_BAND
, band_ctrl
) |
194 FIELD_PREP(DPHY_BAND_CFG_RIGHT_BAND
, band_ctrl
);
195 writel(reg
, dphy
->regs
+ DPHY_BAND_CFG
);
198 * Set the required power island phase 2 time. This is mandated by DPHY
201 reg
= DPHY_POWER_ISLAND_EN_DATA_VAL
;
202 writel(reg
, dphy
->regs
+ DPHY_POWER_ISLAND_EN_DATA
);
203 reg
= DPHY_POWER_ISLAND_EN_CLK_VAL
;
204 writel(reg
, dphy
->regs
+ DPHY_POWER_ISLAND_EN_CLK
);
206 ret
= cdns_dphy_rx_wait_lane_ready(dphy
, lanes
);
208 dev_err(dphy
->dev
, "DPHY wait for lane ready timeout\n");
215 static int cdns_dphy_rx_validate(struct phy
*phy
, enum phy_mode mode
,
216 int submode
, union phy_configure_opts
*opts
)
220 if (mode
!= PHY_MODE_MIPI_DPHY
)
223 ret
= cdns_dphy_rx_get_band_ctrl(opts
->mipi_dphy
.hs_clk_rate
);
227 return phy_mipi_dphy_config_validate(&opts
->mipi_dphy
);
230 static const struct phy_ops cdns_dphy_rx_ops
= {
231 .power_on
= cdns_dphy_rx_power_on
,
232 .power_off
= cdns_dphy_rx_power_off
,
233 .configure
= cdns_dphy_rx_configure
,
234 .validate
= cdns_dphy_rx_validate
,
237 static int cdns_dphy_rx_probe(struct platform_device
*pdev
)
239 struct device
*dev
= &pdev
->dev
;
240 struct phy_provider
*provider
;
241 struct cdns_dphy_rx
*dphy
;
243 dphy
= devm_kzalloc(dev
, sizeof(*dphy
), GFP_KERNEL
);
247 dev_set_drvdata(dev
, dphy
);
250 dphy
->regs
= devm_platform_ioremap_resource(pdev
, 0);
251 if (IS_ERR(dphy
->regs
))
252 return PTR_ERR(dphy
->regs
);
254 dphy
->phy
= devm_phy_create(dev
, NULL
, &cdns_dphy_rx_ops
);
255 if (IS_ERR(dphy
->phy
)) {
256 dev_err(dev
, "Failed to create PHY: %ld\n", PTR_ERR(dphy
->phy
));
257 return PTR_ERR(dphy
->phy
);
260 phy_set_drvdata(dphy
->phy
, dphy
);
261 provider
= devm_of_phy_provider_register(dev
, of_phy_simple_xlate
);
262 if (IS_ERR(provider
)) {
263 dev_err(dev
, "Failed to register PHY provider: %ld\n",
265 return PTR_ERR(provider
);
271 static const struct of_device_id cdns_dphy_rx_of_match
[] = {
272 { .compatible
= "cdns,dphy-rx" },
275 MODULE_DEVICE_TABLE(of
, cdns_dphy_rx_of_match
);
277 static struct platform_driver cdns_dphy_rx_platform_driver
= {
278 .probe
= cdns_dphy_rx_probe
,
280 .name
= "cdns-mipi-dphy-rx",
281 .of_match_table
= cdns_dphy_rx_of_match
,
284 module_platform_driver(cdns_dphy_rx_platform_driver
);
286 MODULE_AUTHOR("Pratyush Yadav <p.yadav@ti.com>");
287 MODULE_DESCRIPTION("Cadence D-PHY Rx Driver");
288 MODULE_LICENSE("GPL");