blob: 027667a17ebe98a66c51167cda804bbf3f93b0f0 [file] [log] [blame]
Scott Telfordc8b427e2018-08-09 11:30:30 +01001// SPDX-License-Identifier: GPL-2.0-only
2/*
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +01003 * Cadence Torrent SD0801 PHY driver.
Scott Telfordc8b427e2018-08-09 11:30:30 +01004 *
5 * Copyright 2018 Cadence Design Systems, Inc.
6 *
7 */
8
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01009#include <linux/clk.h>
Scott Telfordc8b427e2018-08-09 11:30:30 +010010#include <linux/delay.h>
11#include <linux/err.h>
12#include <linux/io.h>
13#include <linux/iopoll.h>
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/of_address.h>
18#include <linux/of_device.h>
19#include <linux/phy/phy.h>
20#include <linux/platform_device.h>
Swapnil Jakhade69d114a2020-02-06 07:10:58 +010021#include <linux/regmap.h>
Scott Telfordc8b427e2018-08-09 11:30:30 +010022
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +010023#define REF_CLK_19_2MHz 19200000
24#define REF_CLK_25MHz 25000000
25
26#define DEFAULT_NUM_LANES 4
Scott Telfordc8b427e2018-08-09 11:30:30 +010027#define MAX_NUM_LANES 4
28#define DEFAULT_MAX_BIT_RATE 8100 /* in Mbps */
29
Swapnil Jakhade21c79142020-02-06 07:10:55 +010030#define POLL_TIMEOUT_US 5000
Swapnil Jakhade69d114a2020-02-06 07:10:58 +010031
32#define TORRENT_COMMON_CDB_OFFSET 0x0
33
34#define TORRENT_TX_LANE_CDB_OFFSET(ln, block_offset, reg_offset) \
35 ((0x4000 << (block_offset)) + \
36 (((ln) << 9) << (reg_offset)))
37
38#define TORRENT_RX_LANE_CDB_OFFSET(ln, block_offset, reg_offset) \
39 ((0x8000 << (block_offset)) + \
40 (((ln) << 9) << (reg_offset)))
41
42#define TORRENT_PHY_PCS_COMMON_OFFSET(block_offset) \
43 (0xC000 << (block_offset))
44
45#define TORRENT_PHY_PMA_COMMON_OFFSET(block_offset) \
46 (0xE000 << (block_offset))
Scott Telfordc8b427e2018-08-09 11:30:30 +010047
48/*
49 * register offsets from DPTX PHY register block base (i.e MHDP
50 * register base + 0x30a00)
51 */
52#define PHY_AUX_CONFIG 0x00
53#define PHY_AUX_CTRL 0x04
54#define PHY_RESET 0x20
Swapnil Jakhade572d6592020-02-06 07:10:57 +010055#define PMA_TX_ELEC_IDLE_MASK 0xF0U
56#define PMA_TX_ELEC_IDLE_SHIFT 4
57#define PHY_L00_RESET_N_MASK 0x01U
Scott Telfordc8b427e2018-08-09 11:30:30 +010058#define PHY_PMA_XCVR_PLLCLK_EN 0x24
59#define PHY_PMA_XCVR_PLLCLK_EN_ACK 0x28
60#define PHY_PMA_XCVR_POWER_STATE_REQ 0x2c
61#define PHY_POWER_STATE_LN_0 0x0000
62#define PHY_POWER_STATE_LN_1 0x0008
63#define PHY_POWER_STATE_LN_2 0x0010
64#define PHY_POWER_STATE_LN_3 0x0018
Swapnil Jakhade21c79142020-02-06 07:10:55 +010065#define PMA_XCVR_POWER_STATE_REQ_LN_MASK 0x3FU
Scott Telfordc8b427e2018-08-09 11:30:30 +010066#define PHY_PMA_XCVR_POWER_STATE_ACK 0x30
67#define PHY_PMA_CMN_READY 0x34
68#define PHY_PMA_XCVR_TX_VMARGIN 0x38
69#define PHY_PMA_XCVR_TX_DEEMPH 0x3c
70
71/*
72 * register offsets from SD0801 PHY register block base (i.e MHDP
73 * register base + 0x500000)
74 */
Swapnil Jakhade69d114a2020-02-06 07:10:58 +010075#define CMN_SSM_BANDGAP_TMR 0x0021U
76#define CMN_SSM_BIAS_TMR 0x0022U
77#define CMN_PLLSM0_PLLPRE_TMR 0x002AU
78#define CMN_PLLSM0_PLLLOCK_TMR 0x002CU
79#define CMN_PLLSM1_PLLPRE_TMR 0x0032U
80#define CMN_PLLSM1_PLLLOCK_TMR 0x0034U
81#define CMN_BGCAL_INIT_TMR 0x0064U
82#define CMN_BGCAL_ITER_TMR 0x0065U
83#define CMN_IBCAL_INIT_TMR 0x0074U
84#define CMN_PLL0_VCOCAL_TCTRL 0x0082U
85#define CMN_PLL0_VCOCAL_INIT_TMR 0x0084U
86#define CMN_PLL0_VCOCAL_ITER_TMR 0x0085U
87#define CMN_PLL0_VCOCAL_REFTIM_START 0x0086U
88#define CMN_PLL0_VCOCAL_PLLCNT_START 0x0088U
89#define CMN_PLL0_INTDIV_M0 0x0090U
90#define CMN_PLL0_FRACDIVL_M0 0x0091U
91#define CMN_PLL0_FRACDIVH_M0 0x0092U
92#define CMN_PLL0_HIGH_THR_M0 0x0093U
93#define CMN_PLL0_DSM_DIAG_M0 0x0094U
94#define CMN_PLL0_SS_CTRL1_M0 0x0098U
95#define CMN_PLL0_SS_CTRL2_M0 0x0099U
96#define CMN_PLL0_SS_CTRL3_M0 0x009AU
97#define CMN_PLL0_SS_CTRL4_M0 0x009BU
98#define CMN_PLL0_LOCK_REFCNT_START 0x009CU
99#define CMN_PLL0_LOCK_PLLCNT_START 0x009EU
100#define CMN_PLL0_LOCK_PLLCNT_THR 0x009FU
101#define CMN_PLL1_VCOCAL_TCTRL 0x00C2U
102#define CMN_PLL1_VCOCAL_INIT_TMR 0x00C4U
103#define CMN_PLL1_VCOCAL_ITER_TMR 0x00C5U
104#define CMN_PLL1_VCOCAL_REFTIM_START 0x00C6U
105#define CMN_PLL1_VCOCAL_PLLCNT_START 0x00C8U
106#define CMN_PLL1_INTDIV_M0 0x00D0U
107#define CMN_PLL1_FRACDIVL_M0 0x00D1U
108#define CMN_PLL1_FRACDIVH_M0 0x00D2U
109#define CMN_PLL1_HIGH_THR_M0 0x00D3U
110#define CMN_PLL1_DSM_DIAG_M0 0x00D4U
111#define CMN_PLL1_SS_CTRL1_M0 0x00D8U
112#define CMN_PLL1_SS_CTRL2_M0 0x00D9U
113#define CMN_PLL1_SS_CTRL3_M0 0x00DAU
114#define CMN_PLL1_SS_CTRL4_M0 0x00DBU
115#define CMN_PLL1_LOCK_REFCNT_START 0x00DCU
116#define CMN_PLL1_LOCK_PLLCNT_START 0x00DEU
117#define CMN_PLL1_LOCK_PLLCNT_THR 0x00DFU
118#define CMN_TXPUCAL_INIT_TMR 0x0104U
119#define CMN_TXPUCAL_ITER_TMR 0x0105U
120#define CMN_TXPDCAL_INIT_TMR 0x010CU
121#define CMN_TXPDCAL_ITER_TMR 0x010DU
122#define CMN_RXCAL_INIT_TMR 0x0114U
123#define CMN_RXCAL_ITER_TMR 0x0115U
124#define CMN_SD_CAL_INIT_TMR 0x0124U
125#define CMN_SD_CAL_ITER_TMR 0x0125U
126#define CMN_SD_CAL_REFTIM_START 0x0126U
127#define CMN_SD_CAL_PLLCNT_START 0x0128U
128#define CMN_PDIAG_PLL0_CTRL_M0 0x01A0U
129#define CMN_PDIAG_PLL0_CLK_SEL_M0 0x01A1U
130#define CMN_PDIAG_PLL0_CP_PADJ_M0 0x01A4U
131#define CMN_PDIAG_PLL0_CP_IADJ_M0 0x01A5U
132#define CMN_PDIAG_PLL0_FILT_PADJ_M0 0x01A6U
133#define CMN_PDIAG_PLL0_CP_PADJ_M1 0x01B4U
134#define CMN_PDIAG_PLL0_CP_IADJ_M1 0x01B5U
135#define CMN_PDIAG_PLL1_CTRL_M0 0x01C0U
136#define CMN_PDIAG_PLL1_CLK_SEL_M0 0x01C1U
137#define CMN_PDIAG_PLL1_CP_PADJ_M0 0x01C4U
138#define CMN_PDIAG_PLL1_CP_IADJ_M0 0x01C5U
139#define CMN_PDIAG_PLL1_FILT_PADJ_M0 0x01C6U
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100140
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100141/* PMA TX Lane registers */
142#define TX_TXCC_CTRL 0x0040U
143#define TX_TXCC_CPOST_MULT_00 0x004CU
144#define TX_TXCC_MGNFS_MULT_000 0x0050U
145#define DRV_DIAG_TX_DRV 0x00C6U
146#define XCVR_DIAG_PLLDRC_CTRL 0x00E5U
147#define XCVR_DIAG_HSCLK_SEL 0x00E6U
148#define XCVR_DIAG_HSCLK_DIV 0x00E7U
149#define XCVR_DIAG_BIDI_CTRL 0x00EAU
150#define TX_PSC_A0 0x0100U
151#define TX_PSC_A2 0x0102U
152#define TX_PSC_A3 0x0103U
153#define TX_RCVDET_ST_TMR 0x0123U
154#define TX_DIAG_ACYA 0x01E7U
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100155#define TX_DIAG_ACYA_HBDC_MASK 0x0001U
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100156
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100157/* PMA RX Lane registers */
158#define RX_PSC_A0 0x0000U
159#define RX_PSC_A2 0x0002U
160#define RX_PSC_A3 0x0003U
161#define RX_PSC_CAL 0x0006U
162#define RX_REE_GCSM1_CTRL 0x0108U
163#define RX_REE_GCSM2_CTRL 0x0110U
164#define RX_REE_PERGCSM_CTRL 0x0118U
Scott Telfordc8b427e2018-08-09 11:30:30 +0100165
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100166/* PHY PCS common registers */
167#define PHY_PLL_CFG 0x000EU
168
169/* PHY PMA common registers */
170#define PHY_PMA_CMN_CTRL2 0x0001U
171#define PHY_PMA_PLL_RAW_CTRL 0x0003U
172
173static const struct reg_field phy_pll_cfg =
174 REG_FIELD(PHY_PLL_CFG, 0, 1);
175
176static const struct reg_field phy_pma_cmn_ctrl_2 =
177 REG_FIELD(PHY_PMA_CMN_CTRL2, 0, 7);
178
179static const struct reg_field phy_pma_pll_raw_ctrl =
180 REG_FIELD(PHY_PMA_PLL_RAW_CTRL, 0, 1);
181
182static const struct of_device_id cdns_torrent_phy_of_match[];
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100183
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +0100184struct cdns_torrent_phy {
Scott Telfordc8b427e2018-08-09 11:30:30 +0100185 void __iomem *base; /* DPTX registers base */
186 void __iomem *sd_base; /* SD0801 registers base */
187 u32 num_lanes; /* Number of lanes to use */
188 u32 max_bit_rate; /* Maximum link bit rate to use (in Mbps) */
189 struct device *dev;
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100190 struct clk *clk;
191 unsigned long ref_clk_rate;
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100192 struct regmap *regmap;
193 struct regmap *regmap_common_cdb;
194 struct regmap *regmap_phy_pcs_common_cdb;
195 struct regmap *regmap_phy_pma_common_cdb;
196 struct regmap *regmap_tx_lane_cdb[MAX_NUM_LANES];
197 struct regmap *regmap_rx_lane_cdb[MAX_NUM_LANES];
198 struct regmap_field *phy_pll_cfg;
199 struct regmap_field *phy_pma_cmn_ctrl_2;
200 struct regmap_field *phy_pma_pll_raw_ctrl;
Scott Telfordc8b427e2018-08-09 11:30:30 +0100201};
202
Swapnil Jakhade21c79142020-02-06 07:10:55 +0100203enum phy_powerstate {
204 POWERSTATE_A0 = 0,
205 /* Powerstate A1 is unused */
206 POWERSTATE_A2 = 2,
207 POWERSTATE_A3 = 3,
208};
209
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +0100210static int cdns_torrent_dp_init(struct phy *phy);
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100211static int cdns_torrent_dp_exit(struct phy *phy);
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100212static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy,
213 u32 num_lanes);
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +0100214static
Swapnil Jakhade21c79142020-02-06 07:10:55 +0100215int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy);
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +0100216static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy);
217static
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100218void cdns_torrent_dp_pma_cmn_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy);
219static
220void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy,
221 u32 rate, bool ssc);
222static
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +0100223void cdns_torrent_dp_pma_cmn_cfg_25mhz(struct cdns_torrent_phy *cdns_phy);
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100224static
225void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy,
226 u32 rate, bool ssc);
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +0100227static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy,
Scott Telfordc8b427e2018-08-09 11:30:30 +0100228 unsigned int lane);
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100229static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy,
230 u32 rate, u32 num_lanes);
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +0100231static void cdns_dp_phy_write_field(struct cdns_torrent_phy *cdns_phy,
232 unsigned int offset,
233 unsigned char start_bit,
234 unsigned char num_bits,
235 unsigned int val);
Scott Telfordc8b427e2018-08-09 11:30:30 +0100236
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100237static int cdns_torrent_dp_configure(struct phy *phy,
238 union phy_configure_opts *opts);
239static int cdns_torrent_dp_set_power_state(struct cdns_torrent_phy *cdns_phy,
240 u32 num_lanes,
241 enum phy_powerstate powerstate);
242
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +0100243static const struct phy_ops cdns_torrent_phy_ops = {
244 .init = cdns_torrent_dp_init,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100245 .exit = cdns_torrent_dp_exit,
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100246 .configure = cdns_torrent_dp_configure,
Scott Telfordc8b427e2018-08-09 11:30:30 +0100247 .owner = THIS_MODULE,
248};
249
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100250struct cdns_torrent_data {
251 u8 block_offset_shift;
252 u8 reg_offset_shift;
253};
254
255struct cdns_regmap_cdb_context {
256 struct device *dev;
257 void __iomem *base;
258 u8 reg_offset_shift;
259};
260
261static int cdns_regmap_write(void *context, unsigned int reg, unsigned int val)
262{
263 struct cdns_regmap_cdb_context *ctx = context;
264 u32 offset = reg << ctx->reg_offset_shift;
265
266 writew(val, ctx->base + offset);
267
268 return 0;
269}
270
271static int cdns_regmap_read(void *context, unsigned int reg, unsigned int *val)
272{
273 struct cdns_regmap_cdb_context *ctx = context;
274 u32 offset = reg << ctx->reg_offset_shift;
275
276 *val = readw(ctx->base + offset);
277 return 0;
278}
279
280#define TORRENT_TX_LANE_CDB_REGMAP_CONF(n) \
281{ \
282 .name = "torrent_tx_lane" n "_cdb", \
283 .reg_stride = 1, \
284 .fast_io = true, \
285 .reg_write = cdns_regmap_write, \
286 .reg_read = cdns_regmap_read, \
287}
288
289#define TORRENT_RX_LANE_CDB_REGMAP_CONF(n) \
290{ \
291 .name = "torrent_rx_lane" n "_cdb", \
292 .reg_stride = 1, \
293 .fast_io = true, \
294 .reg_write = cdns_regmap_write, \
295 .reg_read = cdns_regmap_read, \
296}
297
298static struct regmap_config cdns_torrent_tx_lane_cdb_config[] = {
299 TORRENT_TX_LANE_CDB_REGMAP_CONF("0"),
300 TORRENT_TX_LANE_CDB_REGMAP_CONF("1"),
301 TORRENT_TX_LANE_CDB_REGMAP_CONF("2"),
302 TORRENT_TX_LANE_CDB_REGMAP_CONF("3"),
303};
304
305static struct regmap_config cdns_torrent_rx_lane_cdb_config[] = {
306 TORRENT_RX_LANE_CDB_REGMAP_CONF("0"),
307 TORRENT_RX_LANE_CDB_REGMAP_CONF("1"),
308 TORRENT_RX_LANE_CDB_REGMAP_CONF("2"),
309 TORRENT_RX_LANE_CDB_REGMAP_CONF("3"),
310};
311
312static struct regmap_config cdns_torrent_common_cdb_config = {
313 .name = "torrent_common_cdb",
314 .reg_stride = 1,
315 .fast_io = true,
316 .reg_write = cdns_regmap_write,
317 .reg_read = cdns_regmap_read,
318};
319
320static struct regmap_config cdns_torrent_phy_pcs_cmn_cdb_config = {
321 .name = "torrent_phy_pcs_cmn_cdb",
322 .reg_stride = 1,
323 .fast_io = true,
324 .reg_write = cdns_regmap_write,
325 .reg_read = cdns_regmap_read,
326};
327
328static struct regmap_config cdns_torrent_phy_pma_cmn_cdb_config = {
329 .name = "torrent_phy_pma_cmn_cdb",
330 .reg_stride = 1,
331 .fast_io = true,
332 .reg_write = cdns_regmap_write,
333 .reg_read = cdns_regmap_read,
334};
335
Swapnil Jakhadeccb1b892020-02-06 07:10:53 +0100336/* PHY mmr access functions */
337
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100338static void cdns_torrent_phy_write(struct regmap *regmap, u32 offset, u32 val)
Swapnil Jakhadeccb1b892020-02-06 07:10:53 +0100339{
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100340 regmap_write(regmap, offset, val);
Swapnil Jakhadeccb1b892020-02-06 07:10:53 +0100341}
342
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100343static u32 cdns_torrent_phy_read(struct regmap *regmap, u32 offset)
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100344{
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100345 unsigned int val;
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100346
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100347 regmap_read(regmap, offset, &val);
348 return val;
349}
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100350
Swapnil Jakhadef61b3ae2020-02-06 07:10:54 +0100351/* DPTX mmr access functions */
352
353static void cdns_torrent_dp_write(struct cdns_torrent_phy *cdns_phy,
354 u32 offset, u32 val)
355{
356 writel(val, cdns_phy->base + offset);
357}
358
359static u32 cdns_torrent_dp_read(struct cdns_torrent_phy *cdns_phy, u32 offset)
360{
361 return readl(cdns_phy->base + offset);
362}
363
364#define cdns_torrent_dp_read_poll_timeout(cdns_phy, offset, val, cond, \
365 delay_us, timeout_us) \
366 readl_poll_timeout((cdns_phy)->base + (offset), \
367 val, cond, delay_us, timeout_us)
368
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100369/*
370 * Structure used to store values of PHY registers for voltage-related
371 * coefficients, for particular voltage swing and pre-emphasis level. Values
372 * are shared across all physical lanes.
373 */
374struct coefficients {
375 /* Value of DRV_DIAG_TX_DRV register to use */
376 u16 diag_tx_drv;
377 /* Value of TX_TXCC_MGNFS_MULT_000 register to use */
378 u16 mgnfs_mult;
379 /* Value of TX_TXCC_CPOST_MULT_00 register to use */
380 u16 cpost_mult;
381};
382
383/*
384 * Array consists of values of voltage-related registers for sd0801 PHY. A value
385 * of 0xFFFF is a placeholder for invalid combination, and will never be used.
386 */
387static const struct coefficients vltg_coeff[4][4] = {
388 /* voltage swing 0, pre-emphasis 0->3 */
389 { {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x002A,
390 .cpost_mult = 0x0000},
391 {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x001F,
392 .cpost_mult = 0x0014},
393 {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0012,
394 .cpost_mult = 0x0020},
395 {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0000,
396 .cpost_mult = 0x002A}
397 },
398
399 /* voltage swing 1, pre-emphasis 0->3 */
400 { {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x001F,
401 .cpost_mult = 0x0000},
402 {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0013,
403 .cpost_mult = 0x0012},
404 {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0000,
405 .cpost_mult = 0x001F},
406 {.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF,
407 .cpost_mult = 0xFFFF}
408 },
409
410 /* voltage swing 2, pre-emphasis 0->3 */
411 { {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0013,
412 .cpost_mult = 0x0000},
413 {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0000,
414 .cpost_mult = 0x0013},
415 {.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF,
416 .cpost_mult = 0xFFFF},
417 {.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF,
418 .cpost_mult = 0xFFFF}
419 },
420
421 /* voltage swing 3, pre-emphasis 0->3 */
422 { {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0000,
423 .cpost_mult = 0x0000},
424 {.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF,
425 .cpost_mult = 0xFFFF},
426 {.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF,
427 .cpost_mult = 0xFFFF},
428 {.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF,
429 .cpost_mult = 0xFFFF}
430 }
431};
432
433/*
434 * Enable or disable PLL for selected lanes.
435 */
436static int cdns_torrent_dp_set_pll_en(struct cdns_torrent_phy *cdns_phy,
437 struct phy_configure_opts_dp *dp,
438 bool enable)
439{
440 u32 rd_val;
441 u32 ret;
442 /*
443 * Used to determine, which bits to check for or enable in
444 * PHY_PMA_XCVR_PLLCLK_EN register.
445 */
446 u32 pll_bits;
447 /* Used to enable or disable lanes. */
448 u32 pll_val;
449
450 /* Select values of registers and mask, depending on enabled lane
451 * count.
452 */
453 switch (dp->lanes) {
454 /* lane 0 */
455 case (1):
456 pll_bits = 0x00000001;
457 break;
458 /* lanes 0-1 */
459 case (2):
460 pll_bits = 0x00000003;
461 break;
462 /* lanes 0-3, all */
463 default:
464 pll_bits = 0x0000000F;
465 break;
466 }
467
468 if (enable)
469 pll_val = pll_bits;
470 else
471 pll_val = 0x00000000;
472
473 cdns_torrent_dp_write(cdns_phy, PHY_PMA_XCVR_PLLCLK_EN, pll_val);
474
475 /* Wait for acknowledgment from PHY. */
476 ret = cdns_torrent_dp_read_poll_timeout(cdns_phy,
477 PHY_PMA_XCVR_PLLCLK_EN_ACK,
478 rd_val,
479 (rd_val & pll_bits) == pll_val,
480 0, POLL_TIMEOUT_US);
481 ndelay(100);
482 return ret;
483}
484
485/*
486 * Perform register operations related to setting link rate, once powerstate is
487 * set and PLL disable request was processed.
488 */
489static int cdns_torrent_dp_configure_rate(struct cdns_torrent_phy *cdns_phy,
490 struct phy_configure_opts_dp *dp)
491{
492 u32 ret;
493 u32 read_val;
494
495 /* Disable the cmn_pll0_en before re-programming the new data rate. */
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100496 regmap_field_write(cdns_phy->phy_pma_pll_raw_ctrl, 0x0);
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100497
498 /*
499 * Wait for PLL ready de-assertion.
500 * For PLL0 - PHY_PMA_CMN_CTRL2[2] == 1
501 */
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100502 ret = regmap_field_read_poll_timeout(cdns_phy->phy_pma_cmn_ctrl_2,
503 read_val,
504 ((read_val >> 2) & 0x01) != 0,
505 0, POLL_TIMEOUT_US);
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100506 if (ret)
507 return ret;
508 ndelay(200);
509
510 /* DP Rate Change - VCO Output settings. */
511 if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz) {
512 /* PMA common configuration 19.2MHz */
513 cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, dp->link_rate,
514 dp->ssc);
515 cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy);
516 } else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz) {
517 /* PMA common configuration 25MHz */
518 cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, dp->link_rate,
519 dp->ssc);
520 cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy);
521 }
522 cdns_torrent_dp_pma_cmn_rate(cdns_phy, dp->link_rate, dp->lanes);
523
524 /* Enable the cmn_pll0_en. */
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100525 regmap_field_write(cdns_phy->phy_pma_pll_raw_ctrl, 0x3);
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100526
527 /*
528 * Wait for PLL ready assertion.
529 * For PLL0 - PHY_PMA_CMN_CTRL2[0] == 1
530 */
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100531 ret = regmap_field_read_poll_timeout(cdns_phy->phy_pma_cmn_ctrl_2,
532 read_val,
533 (read_val & 0x01) != 0,
534 0, POLL_TIMEOUT_US);
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100535 return ret;
536}
537
538/*
539 * Verify, that parameters to configure PHY with are correct.
540 */
541static int cdns_torrent_dp_verify_config(struct cdns_torrent_phy *cdns_phy,
542 struct phy_configure_opts_dp *dp)
543{
544 u8 i;
545
546 /* If changing link rate was required, verify it's supported. */
547 if (dp->set_rate) {
548 switch (dp->link_rate) {
549 case 1620:
550 case 2160:
551 case 2430:
552 case 2700:
553 case 3240:
554 case 4320:
555 case 5400:
556 case 8100:
557 /* valid bit rate */
558 break;
559 default:
560 return -EINVAL;
561 }
562 }
563
564 /* Verify lane count. */
565 switch (dp->lanes) {
566 case 1:
567 case 2:
568 case 4:
569 /* valid lane count. */
570 break;
571 default:
572 return -EINVAL;
573 }
574
575 /* Check against actual number of PHY's lanes. */
576 if (dp->lanes > cdns_phy->num_lanes)
577 return -EINVAL;
578
579 /*
580 * If changing voltages is required, check swing and pre-emphasis
581 * levels, per-lane.
582 */
583 if (dp->set_voltages) {
584 /* Lane count verified previously. */
585 for (i = 0; i < dp->lanes; i++) {
586 if (dp->voltage[i] > 3 || dp->pre[i] > 3)
587 return -EINVAL;
588
589 /* Sum of voltage swing and pre-emphasis levels cannot
590 * exceed 3.
591 */
592 if (dp->voltage[i] + dp->pre[i] > 3)
593 return -EINVAL;
594 }
595 }
596
597 return 0;
598}
599
Swapnil Jakhade21c79142020-02-06 07:10:55 +0100600/* Set power state A0 and PLL clock enable to 0 on enabled lanes. */
601static void cdns_torrent_dp_set_a0_pll(struct cdns_torrent_phy *cdns_phy,
602 u32 num_lanes)
603{
604 u32 pwr_state = cdns_torrent_dp_read(cdns_phy,
605 PHY_PMA_XCVR_POWER_STATE_REQ);
606 u32 pll_clk_en = cdns_torrent_dp_read(cdns_phy,
607 PHY_PMA_XCVR_PLLCLK_EN);
608
609 /* Lane 0 is always enabled. */
610 pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK <<
611 PHY_POWER_STATE_LN_0);
612 pll_clk_en &= ~0x01U;
613
614 if (num_lanes > 1) {
615 /* lane 1 */
616 pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK <<
617 PHY_POWER_STATE_LN_1);
618 pll_clk_en &= ~(0x01U << 1);
619 }
620
621 if (num_lanes > 2) {
622 /* lanes 2 and 3 */
623 pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK <<
624 PHY_POWER_STATE_LN_2);
625 pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK <<
626 PHY_POWER_STATE_LN_3);
627 pll_clk_en &= ~(0x01U << 2);
628 pll_clk_en &= ~(0x01U << 3);
629 }
630
631 cdns_torrent_dp_write(cdns_phy,
632 PHY_PMA_XCVR_POWER_STATE_REQ, pwr_state);
633 cdns_torrent_dp_write(cdns_phy, PHY_PMA_XCVR_PLLCLK_EN, pll_clk_en);
634}
635
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100636/* Configure lane count as required. */
637static int cdns_torrent_dp_set_lanes(struct cdns_torrent_phy *cdns_phy,
638 struct phy_configure_opts_dp *dp)
639{
640 u32 value;
641 u32 ret;
642 u8 lane_mask = (1 << dp->lanes) - 1;
643
644 value = cdns_torrent_dp_read(cdns_phy, PHY_RESET);
645 /* clear pma_tx_elec_idle_ln_* bits. */
646 value &= ~PMA_TX_ELEC_IDLE_MASK;
647 /* Assert pma_tx_elec_idle_ln_* for disabled lanes. */
648 value |= ((~lane_mask) << PMA_TX_ELEC_IDLE_SHIFT) &
649 PMA_TX_ELEC_IDLE_MASK;
650 cdns_torrent_dp_write(cdns_phy, PHY_RESET, value);
651
652 /* reset the link by asserting phy_l00_reset_n low */
653 cdns_torrent_dp_write(cdns_phy, PHY_RESET,
654 value & (~PHY_L00_RESET_N_MASK));
655
656 /*
657 * Assert lane reset on unused lanes and lane 0 so they remain in reset
658 * and powered down when re-enabling the link
659 */
660 value = (value & 0x0000FFF0) | (0x0000000E & lane_mask);
661 cdns_torrent_dp_write(cdns_phy, PHY_RESET, value);
662
663 cdns_torrent_dp_set_a0_pll(cdns_phy, dp->lanes);
664
665 /* release phy_l0*_reset_n based on used laneCount */
666 value = (value & 0x0000FFF0) | (0x0000000F & lane_mask);
667 cdns_torrent_dp_write(cdns_phy, PHY_RESET, value);
668
669 /* Wait, until PHY gets ready after releasing PHY reset signal. */
670 ret = cdns_torrent_dp_wait_pma_cmn_ready(cdns_phy);
671 if (ret)
672 return ret;
673
674 ndelay(100);
675
676 /* release pma_xcvr_pllclk_en_ln_*, only for the master lane */
677 cdns_torrent_dp_write(cdns_phy, PHY_PMA_XCVR_PLLCLK_EN, 0x0001);
678
679 ret = cdns_torrent_dp_run(cdns_phy, dp->lanes);
680
681 return ret;
682}
683
684/* Configure link rate as required. */
685static int cdns_torrent_dp_set_rate(struct cdns_torrent_phy *cdns_phy,
686 struct phy_configure_opts_dp *dp)
687{
688 u32 ret;
689
690 ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes,
691 POWERSTATE_A3);
692 if (ret)
693 return ret;
694 ret = cdns_torrent_dp_set_pll_en(cdns_phy, dp, false);
695 if (ret)
696 return ret;
697 ndelay(200);
698
699 ret = cdns_torrent_dp_configure_rate(cdns_phy, dp);
700 if (ret)
701 return ret;
702 ndelay(200);
703
704 ret = cdns_torrent_dp_set_pll_en(cdns_phy, dp, true);
705 if (ret)
706 return ret;
707 ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes,
708 POWERSTATE_A2);
709 if (ret)
710 return ret;
711 ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes,
712 POWERSTATE_A0);
713 if (ret)
714 return ret;
715 ndelay(900);
716
717 return ret;
718}
719
720/* Configure voltage swing and pre-emphasis for all enabled lanes. */
721static void cdns_torrent_dp_set_voltages(struct cdns_torrent_phy *cdns_phy,
722 struct phy_configure_opts_dp *dp)
723{
724 u8 lane;
725 u16 val;
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100726
727 for (lane = 0; lane < dp->lanes; lane++) {
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100728 val = cdns_torrent_phy_read(cdns_phy->regmap_tx_lane_cdb[lane],
729 TX_DIAG_ACYA);
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100730 /*
731 * Write 1 to register bit TX_DIAG_ACYA[0] to freeze the
732 * current state of the analog TX driver.
733 */
734 val |= TX_DIAG_ACYA_HBDC_MASK;
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100735 cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
736 TX_DIAG_ACYA, val);
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100737
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100738 cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
739 TX_TXCC_CTRL, 0x08A4);
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100740 val = vltg_coeff[dp->voltage[lane]][dp->pre[lane]].diag_tx_drv;
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100741 cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
742 DRV_DIAG_TX_DRV, val);
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100743 val = vltg_coeff[dp->voltage[lane]][dp->pre[lane]].mgnfs_mult;
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100744 cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
745 TX_TXCC_MGNFS_MULT_000,
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100746 val);
747 val = vltg_coeff[dp->voltage[lane]][dp->pre[lane]].cpost_mult;
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100748 cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
749 TX_TXCC_CPOST_MULT_00,
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100750 val);
751
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100752 val = cdns_torrent_phy_read(cdns_phy->regmap_tx_lane_cdb[lane],
753 TX_DIAG_ACYA);
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100754 /*
755 * Write 0 to register bit TX_DIAG_ACYA[0] to allow the state of
756 * analog TX driver to reflect the new programmed one.
757 */
758 val &= ~TX_DIAG_ACYA_HBDC_MASK;
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100759 cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
760 TX_DIAG_ACYA, val);
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100761 }
762};
763
764static int cdns_torrent_dp_configure(struct phy *phy,
765 union phy_configure_opts *opts)
766{
767 struct cdns_torrent_phy *cdns_phy = phy_get_drvdata(phy);
768 int ret;
769
770 ret = cdns_torrent_dp_verify_config(cdns_phy, &opts->dp);
771 if (ret) {
772 dev_err(&phy->dev, "invalid params for phy configure\n");
773 return ret;
774 }
775
776 if (opts->dp.set_lanes) {
777 ret = cdns_torrent_dp_set_lanes(cdns_phy, &opts->dp);
778 if (ret) {
779 dev_err(&phy->dev, "cdns_torrent_dp_set_lanes failed\n");
780 return ret;
781 }
782 }
783
784 if (opts->dp.set_rate) {
785 ret = cdns_torrent_dp_set_rate(cdns_phy, &opts->dp);
786 if (ret) {
787 dev_err(&phy->dev, "cdns_torrent_dp_set_rate failed\n");
788 return ret;
789 }
790 }
791
792 if (opts->dp.set_voltages)
793 cdns_torrent_dp_set_voltages(cdns_phy, &opts->dp);
794
795 return ret;
796}
797
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +0100798static int cdns_torrent_dp_init(struct phy *phy)
Scott Telfordc8b427e2018-08-09 11:30:30 +0100799{
800 unsigned char lane_bits;
Swapnil Jakhade21c79142020-02-06 07:10:55 +0100801 int ret;
Scott Telfordc8b427e2018-08-09 11:30:30 +0100802
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +0100803 struct cdns_torrent_phy *cdns_phy = phy_get_drvdata(phy);
Scott Telfordc8b427e2018-08-09 11:30:30 +0100804
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100805 ret = clk_prepare_enable(cdns_phy->clk);
806 if (ret) {
807 dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
808 return ret;
809 }
810
811 cdns_phy->ref_clk_rate = clk_get_rate(cdns_phy->clk);
812 if (!(cdns_phy->ref_clk_rate)) {
813 dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
814 clk_disable_unprepare(cdns_phy->clk);
815 return -EINVAL;
816 }
817
818 switch (cdns_phy->ref_clk_rate) {
819 case REF_CLK_19_2MHz:
820 case REF_CLK_25MHz:
821 /* Valid Ref Clock Rate */
822 break;
823 default:
824 dev_err(cdns_phy->dev, "Unsupported Ref Clock Rate\n");
825 return -EINVAL;
826 }
827
Swapnil Jakhadef61b3ae2020-02-06 07:10:54 +0100828 cdns_torrent_dp_write(cdns_phy, PHY_AUX_CTRL, 0x0003); /* enable AUX */
Scott Telfordc8b427e2018-08-09 11:30:30 +0100829
830 /* PHY PMA registers configuration function */
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +0100831 cdns_torrent_dp_pma_cfg(cdns_phy);
Scott Telfordc8b427e2018-08-09 11:30:30 +0100832
833 /*
834 * Set lines power state to A0
835 * Set lines pll clk enable to 0
836 */
Swapnil Jakhade21c79142020-02-06 07:10:55 +0100837 cdns_torrent_dp_set_a0_pll(cdns_phy, cdns_phy->num_lanes);
Scott Telfordc8b427e2018-08-09 11:30:30 +0100838
839 /*
840 * release phy_l0*_reset_n and pma_tx_elec_idle_ln_* based on
841 * used lanes
842 */
843 lane_bits = (1 << cdns_phy->num_lanes) - 1;
Swapnil Jakhadef61b3ae2020-02-06 07:10:54 +0100844 cdns_torrent_dp_write(cdns_phy, PHY_RESET,
845 ((0xF & ~lane_bits) << 4) | (0xF & lane_bits));
Scott Telfordc8b427e2018-08-09 11:30:30 +0100846
847 /* release pma_xcvr_pllclk_en_ln_*, only for the master lane */
Swapnil Jakhadef61b3ae2020-02-06 07:10:54 +0100848 cdns_torrent_dp_write(cdns_phy, PHY_PMA_XCVR_PLLCLK_EN, 0x0001);
Scott Telfordc8b427e2018-08-09 11:30:30 +0100849
850 /* PHY PMA registers configuration functions */
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100851 /* Initialize PHY with max supported link rate, without SSC. */
852 if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz)
853 cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy,
854 cdns_phy->max_bit_rate,
855 false);
856 else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz)
857 cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy,
858 cdns_phy->max_bit_rate,
859 false);
860 cdns_torrent_dp_pma_cmn_rate(cdns_phy, cdns_phy->max_bit_rate,
861 cdns_phy->num_lanes);
Scott Telfordc8b427e2018-08-09 11:30:30 +0100862
863 /* take out of reset */
864 cdns_dp_phy_write_field(cdns_phy, PHY_RESET, 8, 1, 1);
Swapnil Jakhade21c79142020-02-06 07:10:55 +0100865 ret = cdns_torrent_dp_wait_pma_cmn_ready(cdns_phy);
866 if (ret)
867 return ret;
Scott Telfordc8b427e2018-08-09 11:30:30 +0100868
Swapnil Jakhade572d6592020-02-06 07:10:57 +0100869 ret = cdns_torrent_dp_run(cdns_phy, cdns_phy->num_lanes);
Swapnil Jakhade21c79142020-02-06 07:10:55 +0100870
871 return ret;
Scott Telfordc8b427e2018-08-09 11:30:30 +0100872}
873
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100874static int cdns_torrent_dp_exit(struct phy *phy)
875{
876 struct cdns_torrent_phy *cdns_phy = phy_get_drvdata(phy);
877
878 clk_disable_unprepare(cdns_phy->clk);
879 return 0;
880}
881
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +0100882static
Swapnil Jakhade21c79142020-02-06 07:10:55 +0100883int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy)
Scott Telfordc8b427e2018-08-09 11:30:30 +0100884{
885 unsigned int reg;
886 int ret;
887
Swapnil Jakhadef61b3ae2020-02-06 07:10:54 +0100888 ret = cdns_torrent_dp_read_poll_timeout(cdns_phy, PHY_PMA_CMN_READY,
Swapnil Jakhade21c79142020-02-06 07:10:55 +0100889 reg, reg & 1, 0,
890 POLL_TIMEOUT_US);
891 if (ret == -ETIMEDOUT) {
Scott Telfordc8b427e2018-08-09 11:30:30 +0100892 dev_err(cdns_phy->dev,
893 "timeout waiting for PMA common ready\n");
Swapnil Jakhade21c79142020-02-06 07:10:55 +0100894 return -ETIMEDOUT;
895 }
896
897 return 0;
Scott Telfordc8b427e2018-08-09 11:30:30 +0100898}
899
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +0100900static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy)
Scott Telfordc8b427e2018-08-09 11:30:30 +0100901{
902 unsigned int i;
903
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100904 if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz)
905 /* PMA common configuration 19.2MHz */
906 cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy);
907 else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz)
908 /* PMA common configuration 25MHz */
909 cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy);
Scott Telfordc8b427e2018-08-09 11:30:30 +0100910
911 /* PMA lane configuration to deal with multi-link operation */
912 for (i = 0; i < cdns_phy->num_lanes; i++)
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +0100913 cdns_torrent_dp_pma_lane_cfg(cdns_phy, i);
Scott Telfordc8b427e2018-08-09 11:30:30 +0100914}
915
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +0100916static
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100917void cdns_torrent_dp_pma_cmn_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy)
918{
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100919 struct regmap *regmap = cdns_phy->regmap_common_cdb;
920
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100921 /* refclock registers - assumes 19.2 MHz refclock */
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100922 cdns_torrent_phy_write(regmap, CMN_SSM_BIAS_TMR, 0x0014);
923 cdns_torrent_phy_write(regmap, CMN_PLLSM0_PLLPRE_TMR, 0x0027);
924 cdns_torrent_phy_write(regmap, CMN_PLLSM0_PLLLOCK_TMR, 0x00A1);
925 cdns_torrent_phy_write(regmap, CMN_PLLSM1_PLLPRE_TMR, 0x0027);
926 cdns_torrent_phy_write(regmap, CMN_PLLSM1_PLLLOCK_TMR, 0x00A1);
927 cdns_torrent_phy_write(regmap, CMN_BGCAL_INIT_TMR, 0x0060);
928 cdns_torrent_phy_write(regmap, CMN_BGCAL_ITER_TMR, 0x0060);
929 cdns_torrent_phy_write(regmap, CMN_IBCAL_INIT_TMR, 0x0014);
930 cdns_torrent_phy_write(regmap, CMN_TXPUCAL_INIT_TMR, 0x0018);
931 cdns_torrent_phy_write(regmap, CMN_TXPUCAL_ITER_TMR, 0x0005);
932 cdns_torrent_phy_write(regmap, CMN_TXPDCAL_INIT_TMR, 0x0018);
933 cdns_torrent_phy_write(regmap, CMN_TXPDCAL_ITER_TMR, 0x0005);
934 cdns_torrent_phy_write(regmap, CMN_RXCAL_INIT_TMR, 0x0240);
935 cdns_torrent_phy_write(regmap, CMN_RXCAL_ITER_TMR, 0x0005);
936 cdns_torrent_phy_write(regmap, CMN_SD_CAL_INIT_TMR, 0x0002);
937 cdns_torrent_phy_write(regmap, CMN_SD_CAL_ITER_TMR, 0x0002);
938 cdns_torrent_phy_write(regmap, CMN_SD_CAL_REFTIM_START, 0x000B);
939 cdns_torrent_phy_write(regmap, CMN_SD_CAL_PLLCNT_START, 0x0137);
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100940
941 /* PLL registers */
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100942 cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509);
943 cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00);
944 cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08);
945 cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004);
946 cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0509);
947 cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_IADJ_M0, 0x0F00);
948 cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_FILT_PADJ_M0, 0x0F08);
949 cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004);
950 cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_INIT_TMR, 0x00C0);
951 cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_ITER_TMR, 0x0004);
952 cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_INIT_TMR, 0x00C0);
953 cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_ITER_TMR, 0x0004);
954 cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_REFTIM_START, 0x0260);
955 cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_TCTRL, 0x0003);
956 cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_REFTIM_START, 0x0260);
957 cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_TCTRL, 0x0003);
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100958}
959
960/*
961 * Set registers responsible for enabling and configuring SSC, with second and
962 * third register values provided by parameters.
963 */
964static
965void cdns_torrent_dp_enable_ssc_19_2mhz(struct cdns_torrent_phy *cdns_phy,
966 u32 ctrl2_val, u32 ctrl3_val)
967{
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100968 struct regmap *regmap = cdns_phy->regmap_common_cdb;
969
970 cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0001);
971 cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl2_val);
972 cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl3_val);
973 cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0003);
974 cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0001);
975 cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl2_val);
976 cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl3_val);
977 cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0003);
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100978}
979
980static
981void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy,
982 u32 rate, bool ssc)
983{
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100984 struct regmap *regmap = cdns_phy->regmap_common_cdb;
985
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100986 /* Assumes 19.2 MHz refclock */
987 switch (rate) {
988 /* Setting VCO for 10.8GHz */
989 case 2700:
990 case 5400:
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100991 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100992 CMN_PLL0_INTDIV_M0, 0x0119);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100993 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100994 CMN_PLL0_FRACDIVL_M0, 0x4000);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100995 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100996 CMN_PLL0_FRACDIVH_M0, 0x0002);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100997 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +0100998 CMN_PLL0_HIGH_THR_M0, 0x00BC);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +0100999 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001000 CMN_PDIAG_PLL0_CTRL_M0, 0x0012);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001001 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001002 CMN_PLL1_INTDIV_M0, 0x0119);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001003 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001004 CMN_PLL1_FRACDIVL_M0, 0x4000);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001005 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001006 CMN_PLL1_FRACDIVH_M0, 0x0002);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001007 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001008 CMN_PLL1_HIGH_THR_M0, 0x00BC);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001009 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001010 CMN_PDIAG_PLL1_CTRL_M0, 0x0012);
1011 if (ssc)
1012 cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x033A,
1013 0x006A);
1014 break;
1015 /* Setting VCO for 9.72GHz */
1016 case 1620:
1017 case 2430:
1018 case 3240:
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001019 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001020 CMN_PLL0_INTDIV_M0, 0x01FA);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001021 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001022 CMN_PLL0_FRACDIVL_M0, 0x4000);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001023 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001024 CMN_PLL0_FRACDIVH_M0, 0x0002);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001025 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001026 CMN_PLL0_HIGH_THR_M0, 0x0152);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001027 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001028 CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001029 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001030 CMN_PLL1_INTDIV_M0, 0x01FA);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001031 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001032 CMN_PLL1_FRACDIVL_M0, 0x4000);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001033 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001034 CMN_PLL1_FRACDIVH_M0, 0x0002);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001035 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001036 CMN_PLL1_HIGH_THR_M0, 0x0152);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001037 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001038 CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
1039 if (ssc)
1040 cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x05DD,
1041 0x0069);
1042 break;
1043 /* Setting VCO for 8.64GHz */
1044 case 2160:
1045 case 4320:
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001046 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001047 CMN_PLL0_INTDIV_M0, 0x01C2);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001048 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001049 CMN_PLL0_FRACDIVL_M0, 0x0000);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001050 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001051 CMN_PLL0_FRACDIVH_M0, 0x0002);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001052 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001053 CMN_PLL0_HIGH_THR_M0, 0x012C);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001054 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001055 CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001056 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001057 CMN_PLL1_INTDIV_M0, 0x01C2);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001058 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001059 CMN_PLL1_FRACDIVL_M0, 0x0000);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001060 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001061 CMN_PLL1_FRACDIVH_M0, 0x0002);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001062 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001063 CMN_PLL1_HIGH_THR_M0, 0x012C);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001064 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001065 CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
1066 if (ssc)
1067 cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x0536,
1068 0x0069);
1069 break;
1070 /* Setting VCO for 8.1GHz */
1071 case 8100:
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001072 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001073 CMN_PLL0_INTDIV_M0, 0x01A5);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001074 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001075 CMN_PLL0_FRACDIVL_M0, 0xE000);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001076 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001077 CMN_PLL0_FRACDIVH_M0, 0x0002);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001078 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001079 CMN_PLL0_HIGH_THR_M0, 0x011A);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001080 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001081 CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001082 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001083 CMN_PLL1_INTDIV_M0, 0x01A5);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001084 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001085 CMN_PLL1_FRACDIVL_M0, 0xE000);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001086 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001087 CMN_PLL1_FRACDIVH_M0, 0x0002);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001088 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001089 CMN_PLL1_HIGH_THR_M0, 0x011A);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001090 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001091 CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
1092 if (ssc)
1093 cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x04D7,
1094 0x006A);
1095 break;
1096 }
1097
1098 if (ssc) {
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001099 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001100 CMN_PLL0_VCOCAL_PLLCNT_START, 0x025E);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001101 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001102 CMN_PLL0_LOCK_PLLCNT_THR, 0x0005);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001103 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001104 CMN_PLL1_VCOCAL_PLLCNT_START, 0x025E);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001105 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001106 CMN_PLL1_LOCK_PLLCNT_THR, 0x0005);
1107 } else {
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001108 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001109 CMN_PLL0_VCOCAL_PLLCNT_START, 0x0260);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001110 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001111 CMN_PLL1_VCOCAL_PLLCNT_START, 0x0260);
1112 /* Set reset register values to disable SSC */
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001113 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001114 CMN_PLL0_SS_CTRL1_M0, 0x0002);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001115 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001116 CMN_PLL0_SS_CTRL2_M0, 0x0000);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001117 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001118 CMN_PLL0_SS_CTRL3_M0, 0x0000);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001119 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001120 CMN_PLL0_SS_CTRL4_M0, 0x0000);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001121 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001122 CMN_PLL0_LOCK_PLLCNT_THR, 0x0003);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001123 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001124 CMN_PLL1_SS_CTRL1_M0, 0x0002);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001125 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001126 CMN_PLL1_SS_CTRL2_M0, 0x0000);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001127 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001128 CMN_PLL1_SS_CTRL3_M0, 0x0000);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001129 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001130 CMN_PLL1_SS_CTRL4_M0, 0x0000);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001131 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001132 CMN_PLL1_LOCK_PLLCNT_THR, 0x0003);
1133 }
1134
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001135 cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_REFCNT_START, 0x0099);
1136 cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_PLLCNT_START, 0x0099);
1137 cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_REFCNT_START, 0x0099);
1138 cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_PLLCNT_START, 0x0099);
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001139}
1140
1141static
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +01001142void cdns_torrent_dp_pma_cmn_cfg_25mhz(struct cdns_torrent_phy *cdns_phy)
Scott Telfordc8b427e2018-08-09 11:30:30 +01001143{
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001144 struct regmap *regmap = cdns_phy->regmap_common_cdb;
1145
Scott Telfordc8b427e2018-08-09 11:30:30 +01001146 /* refclock registers - assumes 25 MHz refclock */
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001147 cdns_torrent_phy_write(regmap, CMN_SSM_BIAS_TMR, 0x0019);
1148 cdns_torrent_phy_write(regmap, CMN_PLLSM0_PLLPRE_TMR, 0x0032);
1149 cdns_torrent_phy_write(regmap, CMN_PLLSM0_PLLLOCK_TMR, 0x00D1);
1150 cdns_torrent_phy_write(regmap, CMN_PLLSM1_PLLPRE_TMR, 0x0032);
1151 cdns_torrent_phy_write(regmap, CMN_PLLSM1_PLLLOCK_TMR, 0x00D1);
1152 cdns_torrent_phy_write(regmap, CMN_BGCAL_INIT_TMR, 0x007D);
1153 cdns_torrent_phy_write(regmap, CMN_BGCAL_ITER_TMR, 0x007D);
1154 cdns_torrent_phy_write(regmap, CMN_IBCAL_INIT_TMR, 0x0019);
1155 cdns_torrent_phy_write(regmap, CMN_TXPUCAL_INIT_TMR, 0x001E);
1156 cdns_torrent_phy_write(regmap, CMN_TXPUCAL_ITER_TMR, 0x0006);
1157 cdns_torrent_phy_write(regmap, CMN_TXPDCAL_INIT_TMR, 0x001E);
1158 cdns_torrent_phy_write(regmap, CMN_TXPDCAL_ITER_TMR, 0x0006);
1159 cdns_torrent_phy_write(regmap, CMN_RXCAL_INIT_TMR, 0x02EE);
1160 cdns_torrent_phy_write(regmap, CMN_RXCAL_ITER_TMR, 0x0006);
1161 cdns_torrent_phy_write(regmap, CMN_SD_CAL_INIT_TMR, 0x0002);
1162 cdns_torrent_phy_write(regmap, CMN_SD_CAL_ITER_TMR, 0x0002);
1163 cdns_torrent_phy_write(regmap, CMN_SD_CAL_REFTIM_START, 0x000E);
1164 cdns_torrent_phy_write(regmap, CMN_SD_CAL_PLLCNT_START, 0x012B);
Swapnil Jakhadeccb1b892020-02-06 07:10:53 +01001165
Scott Telfordc8b427e2018-08-09 11:30:30 +01001166 /* PLL registers */
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001167 cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509);
1168 cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00);
1169 cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08);
1170 cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004);
1171 cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0509);
1172 cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_IADJ_M0, 0x0F00);
1173 cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_FILT_PADJ_M0, 0x0F08);
1174 cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004);
1175 cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_INIT_TMR, 0x00FA);
1176 cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_ITER_TMR, 0x0004);
1177 cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_INIT_TMR, 0x00FA);
1178 cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_ITER_TMR, 0x0004);
1179 cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_REFTIM_START, 0x0317);
1180 cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_TCTRL, 0x0003);
1181 cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_REFTIM_START, 0x0317);
1182 cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_TCTRL, 0x0003);
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001183}
1184
1185/*
1186 * Set registers responsible for enabling and configuring SSC, with second
1187 * register value provided by a parameter.
1188 */
1189static void cdns_torrent_dp_enable_ssc_25mhz(struct cdns_torrent_phy *cdns_phy,
1190 u32 ctrl2_val)
1191{
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001192 struct regmap *regmap = cdns_phy->regmap_common_cdb;
1193
1194 cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0001);
1195 cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl2_val);
1196 cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x007F);
1197 cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0003);
1198 cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0001);
1199 cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl2_val);
1200 cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x007F);
1201 cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0003);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001202}
1203
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +01001204static
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001205void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy,
1206 u32 rate, bool ssc)
Scott Telfordc8b427e2018-08-09 11:30:30 +01001207{
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001208 struct regmap *regmap = cdns_phy->regmap_common_cdb;
1209
Scott Telfordc8b427e2018-08-09 11:30:30 +01001210 /* Assumes 25 MHz refclock */
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001211 switch (rate) {
Swapnil Jakhadeccb1b892020-02-06 07:10:53 +01001212 /* Setting VCO for 10.8GHz */
Scott Telfordc8b427e2018-08-09 11:30:30 +01001213 case 2700:
1214 case 5400:
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001215 cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x01B0);
1216 cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x0000);
1217 cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
1218 cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0120);
1219 cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x01B0);
1220 cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x0000);
1221 cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
1222 cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0120);
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001223 if (ssc)
1224 cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x0423);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001225 break;
Swapnil Jakhadeccb1b892020-02-06 07:10:53 +01001226 /* Setting VCO for 9.72GHz */
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001227 case 1620:
Scott Telfordc8b427e2018-08-09 11:30:30 +01001228 case 2430:
1229 case 3240:
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001230 cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0184);
1231 cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0xCCCD);
1232 cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
1233 cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0104);
1234 cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0184);
1235 cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0xCCCD);
1236 cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
1237 cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0104);
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001238 if (ssc)
1239 cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x03B9);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001240 break;
Swapnil Jakhadeccb1b892020-02-06 07:10:53 +01001241 /* Setting VCO for 8.64GHz */
Scott Telfordc8b427e2018-08-09 11:30:30 +01001242 case 2160:
1243 case 4320:
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001244 cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0159);
1245 cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x999A);
1246 cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
1247 cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x00E7);
1248 cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0159);
1249 cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x999A);
1250 cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
1251 cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x00E7);
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001252 if (ssc)
1253 cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x034F);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001254 break;
Swapnil Jakhadeccb1b892020-02-06 07:10:53 +01001255 /* Setting VCO for 8.1GHz */
Scott Telfordc8b427e2018-08-09 11:30:30 +01001256 case 8100:
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001257 cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0144);
1258 cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x0000);
1259 cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002);
1260 cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x00D8);
1261 cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0144);
1262 cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x0000);
1263 cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002);
1264 cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x00D8);
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001265 if (ssc)
1266 cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x031A);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001267 break;
1268 }
1269
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001270 cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
1271 cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001272
1273 if (ssc) {
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001274 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001275 CMN_PLL0_VCOCAL_PLLCNT_START, 0x0315);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001276 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001277 CMN_PLL0_LOCK_PLLCNT_THR, 0x0005);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001278 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001279 CMN_PLL1_VCOCAL_PLLCNT_START, 0x0315);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001280 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001281 CMN_PLL1_LOCK_PLLCNT_THR, 0x0005);
1282 } else {
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001283 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001284 CMN_PLL0_VCOCAL_PLLCNT_START, 0x0317);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001285 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001286 CMN_PLL1_VCOCAL_PLLCNT_START, 0x0317);
1287 /* Set reset register values to disable SSC */
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001288 cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0002);
1289 cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL2_M0, 0x0000);
1290 cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL3_M0, 0x0000);
1291 cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0000);
1292 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001293 CMN_PLL0_LOCK_PLLCNT_THR, 0x0003);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001294 cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0002);
1295 cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL2_M0, 0x0000);
1296 cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL3_M0, 0x0000);
1297 cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0000);
1298 cdns_torrent_phy_write(regmap,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001299 CMN_PLL1_LOCK_PLLCNT_THR, 0x0003);
1300 }
1301
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001302 cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_REFCNT_START, 0x00C7);
1303 cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_PLLCNT_START, 0x00C7);
1304 cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_REFCNT_START, 0x00C7);
1305 cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_PLLCNT_START, 0x00C7);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001306}
1307
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001308static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy,
1309 u32 rate, u32 num_lanes)
Scott Telfordc8b427e2018-08-09 11:30:30 +01001310{
1311 unsigned int clk_sel_val = 0;
1312 unsigned int hsclk_div_val = 0;
1313 unsigned int i;
1314
1315 /* 16'h0000 for single DP link configuration */
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001316 regmap_field_write(cdns_phy->phy_pll_cfg, 0x0);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001317
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001318 switch (rate) {
Scott Telfordc8b427e2018-08-09 11:30:30 +01001319 case 1620:
1320 clk_sel_val = 0x0f01;
1321 hsclk_div_val = 2;
1322 break;
1323 case 2160:
1324 case 2430:
1325 case 2700:
1326 clk_sel_val = 0x0701;
Swapnil Jakhadeccb1b892020-02-06 07:10:53 +01001327 hsclk_div_val = 1;
Scott Telfordc8b427e2018-08-09 11:30:30 +01001328 break;
1329 case 3240:
1330 clk_sel_val = 0x0b00;
1331 hsclk_div_val = 2;
1332 break;
1333 case 4320:
1334 case 5400:
1335 clk_sel_val = 0x0301;
1336 hsclk_div_val = 0;
1337 break;
1338 case 8100:
1339 clk_sel_val = 0x0200;
1340 hsclk_div_val = 0;
1341 break;
1342 }
1343
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001344 cdns_torrent_phy_write(cdns_phy->regmap_common_cdb,
Swapnil Jakhadeccb1b892020-02-06 07:10:53 +01001345 CMN_PDIAG_PLL0_CLK_SEL_M0, clk_sel_val);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001346 cdns_torrent_phy_write(cdns_phy->regmap_common_cdb,
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001347 CMN_PDIAG_PLL1_CLK_SEL_M0, clk_sel_val);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001348
1349 /* PMA lane configuration to deal with multi-link operation */
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001350 for (i = 0; i < num_lanes; i++)
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001351 cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[i],
1352 XCVR_DIAG_HSCLK_DIV, hsclk_div_val);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001353}
1354
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +01001355static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy,
1356 unsigned int lane)
Scott Telfordc8b427e2018-08-09 11:30:30 +01001357{
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001358 /* Per lane, refclock-dependent receiver detection setting */
1359 if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz)
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001360 cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
1361 TX_RCVDET_ST_TMR, 0x0780);
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001362 else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz)
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001363 cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
1364 TX_RCVDET_ST_TMR, 0x09C4);
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001365
Scott Telfordc8b427e2018-08-09 11:30:30 +01001366 /* Writing Tx/Rx Power State Controllers registers */
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001367 cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
1368 TX_PSC_A0, 0x00FB);
1369 cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
1370 TX_PSC_A2, 0x04AA);
1371 cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
1372 TX_PSC_A3, 0x04AA);
1373 cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
1374 RX_PSC_A0, 0x0000);
1375 cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
1376 RX_PSC_A2, 0x0000);
1377 cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
1378 RX_PSC_A3, 0x0000);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001379
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001380 cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
1381 RX_PSC_CAL, 0x0000);
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001382
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001383 cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
1384 RX_REE_GCSM1_CTRL, 0x0000);
1385 cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
1386 RX_REE_GCSM2_CTRL, 0x0000);
1387 cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane],
1388 RX_REE_PERGCSM_CTRL, 0x0000);
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001389
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001390 cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
1391 XCVR_DIAG_BIDI_CTRL, 0x000F);
1392 cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
1393 XCVR_DIAG_PLLDRC_CTRL, 0x0001);
1394 cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane],
1395 XCVR_DIAG_HSCLK_SEL, 0x0000);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001396}
1397
Swapnil Jakhade21c79142020-02-06 07:10:55 +01001398static int cdns_torrent_dp_set_power_state(struct cdns_torrent_phy *cdns_phy,
1399 u32 num_lanes,
1400 enum phy_powerstate powerstate)
1401{
1402 /* Register value for power state for a single byte. */
1403 u32 value_part;
1404 u32 value;
1405 u32 mask;
1406 u32 read_val;
1407 u32 ret;
1408
1409 switch (powerstate) {
1410 case (POWERSTATE_A0):
1411 value_part = 0x01U;
1412 break;
1413 case (POWERSTATE_A2):
1414 value_part = 0x04U;
1415 break;
1416 default:
1417 /* Powerstate A3 */
1418 value_part = 0x08U;
1419 break;
1420 }
1421
1422 /* Select values of registers and mask, depending on enabled
1423 * lane count.
1424 */
1425 switch (num_lanes) {
1426 /* lane 0 */
1427 case (1):
1428 value = value_part;
1429 mask = 0x0000003FU;
1430 break;
1431 /* lanes 0-1 */
1432 case (2):
1433 value = (value_part
1434 | (value_part << 8));
1435 mask = 0x00003F3FU;
1436 break;
1437 /* lanes 0-3, all */
1438 default:
1439 value = (value_part
1440 | (value_part << 8)
1441 | (value_part << 16)
1442 | (value_part << 24));
1443 mask = 0x3F3F3F3FU;
1444 break;
1445 }
1446
1447 /* Set power state A<n>. */
1448 cdns_torrent_dp_write(cdns_phy, PHY_PMA_XCVR_POWER_STATE_REQ, value);
1449 /* Wait, until PHY acknowledges power state completion. */
1450 ret = cdns_torrent_dp_read_poll_timeout(cdns_phy,
1451 PHY_PMA_XCVR_POWER_STATE_ACK,
1452 read_val,
1453 (read_val & mask) == value, 0,
1454 POLL_TIMEOUT_US);
1455 cdns_torrent_dp_write(cdns_phy,
1456 PHY_PMA_XCVR_POWER_STATE_REQ, 0x00000000);
1457 ndelay(100);
1458
1459 return ret;
1460}
1461
Swapnil Jakhade572d6592020-02-06 07:10:57 +01001462static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy, u32 num_lanes)
Scott Telfordc8b427e2018-08-09 11:30:30 +01001463{
1464 unsigned int read_val;
Scott Telfordc8b427e2018-08-09 11:30:30 +01001465 int ret;
1466
1467 /*
1468 * waiting for ACK of pma_xcvr_pllclk_en_ln_*, only for the
1469 * master lane
1470 */
Swapnil Jakhadef61b3ae2020-02-06 07:10:54 +01001471 ret = cdns_torrent_dp_read_poll_timeout(cdns_phy,
1472 PHY_PMA_XCVR_PLLCLK_EN_ACK,
1473 read_val, read_val & 1, 0,
1474 POLL_TIMEOUT_US);
Swapnil Jakhade21c79142020-02-06 07:10:55 +01001475 if (ret == -ETIMEDOUT) {
Scott Telfordc8b427e2018-08-09 11:30:30 +01001476 dev_err(cdns_phy->dev,
1477 "timeout waiting for link PLL clock enable ack\n");
Swapnil Jakhade21c79142020-02-06 07:10:55 +01001478 return ret;
Scott Telfordc8b427e2018-08-09 11:30:30 +01001479 }
1480
Scott Telfordc8b427e2018-08-09 11:30:30 +01001481 ndelay(100);
1482
Swapnil Jakhade572d6592020-02-06 07:10:57 +01001483 ret = cdns_torrent_dp_set_power_state(cdns_phy, num_lanes,
Swapnil Jakhade21c79142020-02-06 07:10:55 +01001484 POWERSTATE_A2);
1485 if (ret)
1486 return ret;
Scott Telfordc8b427e2018-08-09 11:30:30 +01001487
Swapnil Jakhade572d6592020-02-06 07:10:57 +01001488 ret = cdns_torrent_dp_set_power_state(cdns_phy, num_lanes,
Swapnil Jakhade21c79142020-02-06 07:10:55 +01001489 POWERSTATE_A0);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001490
Swapnil Jakhade21c79142020-02-06 07:10:55 +01001491 return ret;
Scott Telfordc8b427e2018-08-09 11:30:30 +01001492}
1493
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +01001494static void cdns_dp_phy_write_field(struct cdns_torrent_phy *cdns_phy,
Scott Telfordc8b427e2018-08-09 11:30:30 +01001495 unsigned int offset,
1496 unsigned char start_bit,
1497 unsigned char num_bits,
1498 unsigned int val)
1499{
1500 unsigned int read_val;
1501
Swapnil Jakhadef61b3ae2020-02-06 07:10:54 +01001502 read_val = cdns_torrent_dp_read(cdns_phy, offset);
1503 cdns_torrent_dp_write(cdns_phy, offset,
1504 ((val << start_bit) |
1505 (read_val & ~(((1 << num_bits) - 1) <<
1506 start_bit))));
Scott Telfordc8b427e2018-08-09 11:30:30 +01001507}
1508
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001509static struct regmap *cdns_regmap_init(struct device *dev, void __iomem *base,
1510 u32 block_offset,
1511 u8 reg_offset_shift,
1512 const struct regmap_config *config)
1513{
1514 struct cdns_regmap_cdb_context *ctx;
1515
1516 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
1517 if (!ctx)
1518 return ERR_PTR(-ENOMEM);
1519
1520 ctx->dev = dev;
1521 ctx->base = base + block_offset;
1522 ctx->reg_offset_shift = reg_offset_shift;
1523
1524 return devm_regmap_init(dev, NULL, ctx, config);
1525}
1526
1527static int cdns_regfield_init(struct cdns_torrent_phy *cdns_phy)
1528{
1529 struct device *dev = cdns_phy->dev;
1530 struct regmap_field *field;
1531 struct regmap *regmap;
1532
1533 regmap = cdns_phy->regmap_phy_pcs_common_cdb;
1534 field = devm_regmap_field_alloc(dev, regmap, phy_pll_cfg);
1535 if (IS_ERR(field)) {
1536 dev_err(dev, "PHY_PLL_CFG reg field init failed\n");
1537 return PTR_ERR(field);
1538 }
1539 cdns_phy->phy_pll_cfg = field;
1540
1541 regmap = cdns_phy->regmap_phy_pma_common_cdb;
1542 field = devm_regmap_field_alloc(dev, regmap, phy_pma_cmn_ctrl_2);
1543 if (IS_ERR(field)) {
1544 dev_err(dev, "PHY_PMA_CMN_CTRL2 reg field init failed\n");
1545 return PTR_ERR(field);
1546 }
1547 cdns_phy->phy_pma_cmn_ctrl_2 = field;
1548
1549 regmap = cdns_phy->regmap_phy_pma_common_cdb;
1550 field = devm_regmap_field_alloc(dev, regmap, phy_pma_pll_raw_ctrl);
1551 if (IS_ERR(field)) {
1552 dev_err(dev, "PHY_PMA_PLL_RAW_CTRL reg field init failed\n");
1553 return PTR_ERR(field);
1554 }
1555 cdns_phy->phy_pma_pll_raw_ctrl = field;
1556
1557 return 0;
1558}
1559
1560static int cdns_regmap_init_torrent_dp(struct cdns_torrent_phy *cdns_phy,
1561 void __iomem *sd_base,
1562 void __iomem *base,
1563 u8 block_offset_shift,
1564 u8 reg_offset_shift)
1565{
1566 struct device *dev = cdns_phy->dev;
1567 struct regmap *regmap;
1568 u32 block_offset;
1569 int i;
1570
1571 for (i = 0; i < MAX_NUM_LANES; i++) {
1572 block_offset = TORRENT_TX_LANE_CDB_OFFSET(i, block_offset_shift,
1573 reg_offset_shift);
1574 regmap = cdns_regmap_init(dev, sd_base, block_offset,
1575 reg_offset_shift,
1576 &cdns_torrent_tx_lane_cdb_config[i]);
1577 if (IS_ERR(regmap)) {
1578 dev_err(dev, "Failed to init tx lane CDB regmap\n");
1579 return PTR_ERR(regmap);
1580 }
1581 cdns_phy->regmap_tx_lane_cdb[i] = regmap;
1582
1583 block_offset = TORRENT_RX_LANE_CDB_OFFSET(i, block_offset_shift,
1584 reg_offset_shift);
1585 regmap = cdns_regmap_init(dev, sd_base, block_offset,
1586 reg_offset_shift,
1587 &cdns_torrent_rx_lane_cdb_config[i]);
1588 if (IS_ERR(regmap)) {
1589 dev_err(dev, "Failed to init rx lane CDB regmap\n");
1590 return PTR_ERR(regmap);
1591 }
1592 cdns_phy->regmap_rx_lane_cdb[i] = regmap;
1593 }
1594
1595 block_offset = TORRENT_COMMON_CDB_OFFSET;
1596 regmap = cdns_regmap_init(dev, sd_base, block_offset,
1597 reg_offset_shift,
1598 &cdns_torrent_common_cdb_config);
1599 if (IS_ERR(regmap)) {
1600 dev_err(dev, "Failed to init common CDB regmap\n");
1601 return PTR_ERR(regmap);
1602 }
1603 cdns_phy->regmap_common_cdb = regmap;
1604
1605 block_offset = TORRENT_PHY_PCS_COMMON_OFFSET(block_offset_shift);
1606 regmap = cdns_regmap_init(dev, sd_base, block_offset,
1607 reg_offset_shift,
1608 &cdns_torrent_phy_pcs_cmn_cdb_config);
1609 if (IS_ERR(regmap)) {
1610 dev_err(dev, "Failed to init PHY PCS common CDB regmap\n");
1611 return PTR_ERR(regmap);
1612 }
1613 cdns_phy->regmap_phy_pcs_common_cdb = regmap;
1614
1615 block_offset = TORRENT_PHY_PMA_COMMON_OFFSET(block_offset_shift);
1616 regmap = cdns_regmap_init(dev, sd_base, block_offset,
1617 reg_offset_shift,
1618 &cdns_torrent_phy_pma_cmn_cdb_config);
1619 if (IS_ERR(regmap)) {
1620 dev_err(dev, "Failed to init PHY PMA common CDB regmap\n");
1621 return PTR_ERR(regmap);
1622 }
1623 cdns_phy->regmap_phy_pma_common_cdb = regmap;
1624
1625 return 0;
1626}
1627
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +01001628static int cdns_torrent_phy_probe(struct platform_device *pdev)
Scott Telfordc8b427e2018-08-09 11:30:30 +01001629{
1630 struct resource *regs;
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +01001631 struct cdns_torrent_phy *cdns_phy;
Scott Telfordc8b427e2018-08-09 11:30:30 +01001632 struct device *dev = &pdev->dev;
1633 struct phy_provider *phy_provider;
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001634 const struct of_device_id *match;
1635 struct cdns_torrent_data *data;
Scott Telfordc8b427e2018-08-09 11:30:30 +01001636 struct phy *phy;
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001637 int err, ret;
1638
1639 /* Get init data for this PHY */
1640 match = of_match_device(cdns_torrent_phy_of_match, dev);
1641 if (!match)
1642 return -EINVAL;
1643
1644 data = (struct cdns_torrent_data *)match->data;
Scott Telfordc8b427e2018-08-09 11:30:30 +01001645
1646 cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL);
1647 if (!cdns_phy)
1648 return -ENOMEM;
1649
1650 cdns_phy->dev = &pdev->dev;
1651
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +01001652 phy = devm_phy_create(dev, NULL, &cdns_torrent_phy_ops);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001653 if (IS_ERR(phy)) {
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +01001654 dev_err(dev, "failed to create Torrent PHY\n");
Scott Telfordc8b427e2018-08-09 11:30:30 +01001655 return PTR_ERR(phy);
1656 }
1657
1658 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001659 cdns_phy->sd_base = devm_ioremap_resource(&pdev->dev, regs);
1660 if (IS_ERR(cdns_phy->sd_base))
1661 return PTR_ERR(cdns_phy->sd_base);
1662
1663 regs = platform_get_resource(pdev, IORESOURCE_MEM, 1);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001664 cdns_phy->base = devm_ioremap_resource(&pdev->dev, regs);
1665 if (IS_ERR(cdns_phy->base))
1666 return PTR_ERR(cdns_phy->base);
1667
Scott Telfordc8b427e2018-08-09 11:30:30 +01001668
1669 err = device_property_read_u32(dev, "num_lanes",
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +01001670 &cdns_phy->num_lanes);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001671 if (err)
1672 cdns_phy->num_lanes = DEFAULT_NUM_LANES;
1673
1674 switch (cdns_phy->num_lanes) {
1675 case 1:
1676 case 2:
1677 case 4:
1678 /* valid number of lanes */
1679 break;
1680 default:
1681 dev_err(dev, "unsupported number of lanes: %d\n",
1682 cdns_phy->num_lanes);
1683 return -EINVAL;
1684 }
1685
1686 err = device_property_read_u32(dev, "max_bit_rate",
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +01001687 &cdns_phy->max_bit_rate);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001688 if (err)
1689 cdns_phy->max_bit_rate = DEFAULT_MAX_BIT_RATE;
1690
1691 switch (cdns_phy->max_bit_rate) {
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001692 case 1620:
Scott Telfordc8b427e2018-08-09 11:30:30 +01001693 case 2160:
1694 case 2430:
1695 case 2700:
1696 case 3240:
1697 case 4320:
1698 case 5400:
1699 case 8100:
1700 /* valid bit rate */
1701 break;
1702 default:
1703 dev_err(dev, "unsupported max bit rate: %dMbps\n",
1704 cdns_phy->max_bit_rate);
1705 return -EINVAL;
1706 }
1707
Swapnil Jakhadee4b496a2020-02-06 07:10:56 +01001708 cdns_phy->clk = devm_clk_get(dev, "refclk");
1709 if (IS_ERR(cdns_phy->clk)) {
1710 dev_err(dev, "phy ref clock not found\n");
1711 return PTR_ERR(cdns_phy->clk);
1712 }
1713
Scott Telfordc8b427e2018-08-09 11:30:30 +01001714 phy_set_drvdata(phy, cdns_phy);
1715
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001716 ret = cdns_regmap_init_torrent_dp(cdns_phy, cdns_phy->sd_base,
1717 cdns_phy->base,
1718 data->block_offset_shift,
1719 data->reg_offset_shift);
1720 if (ret)
1721 return ret;
1722
1723 ret = cdns_regfield_init(cdns_phy);
1724 if (ret)
1725 return ret;
1726
Scott Telfordc8b427e2018-08-09 11:30:30 +01001727 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
1728
1729 dev_info(dev, "%d lanes, max bit rate %d.%03d Gbps\n",
1730 cdns_phy->num_lanes,
1731 cdns_phy->max_bit_rate / 1000,
1732 cdns_phy->max_bit_rate % 1000);
1733
1734 return PTR_ERR_OR_ZERO(phy_provider);
1735}
1736
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001737static const struct cdns_torrent_data cdns_map_torrent = {
1738 .block_offset_shift = 0x2,
1739 .reg_offset_shift = 0x2,
1740};
1741
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +01001742static const struct of_device_id cdns_torrent_phy_of_match[] = {
Scott Telfordc8b427e2018-08-09 11:30:30 +01001743 {
Swapnil Jakhade69d114a2020-02-06 07:10:58 +01001744 .compatible = "cdns,torrent-phy",
1745 .data = &cdns_map_torrent,
Scott Telfordc8b427e2018-08-09 11:30:30 +01001746 },
1747 {}
1748};
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +01001749MODULE_DEVICE_TABLE(of, cdns_torrent_phy_of_match);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001750
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +01001751static struct platform_driver cdns_torrent_phy_driver = {
1752 .probe = cdns_torrent_phy_probe,
Scott Telfordc8b427e2018-08-09 11:30:30 +01001753 .driver = {
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +01001754 .name = "cdns-torrent-phy",
1755 .of_match_table = cdns_torrent_phy_of_match,
Scott Telfordc8b427e2018-08-09 11:30:30 +01001756 }
1757};
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +01001758module_platform_driver(cdns_torrent_phy_driver);
Scott Telfordc8b427e2018-08-09 11:30:30 +01001759
1760MODULE_AUTHOR("Cadence Design Systems, Inc.");
Swapnil Jakhade92e9ccc2020-02-06 07:10:52 +01001761MODULE_DESCRIPTION("Cadence Torrent PHY driver");
Scott Telfordc8b427e2018-08-09 11:30:30 +01001762MODULE_LICENSE("GPL v2");