Merge tag 'for-linus-20190706' of git://git.kernel.dk/linux-block
[linux/fpc-iii.git] / drivers / net / dsa / sja1105 / sja1105_clocking.c
blob94bfe0ee50a8edc4265e8dae641c765dc436de64
1 // SPDX-License-Identifier: BSD-3-Clause
2 /* Copyright (c) 2016-2018, NXP Semiconductors
3 * Copyright (c) 2018-2019, Vladimir Oltean <olteanv@gmail.com>
4 */
5 #include <linux/packing.h>
6 #include "sja1105.h"
8 #define SJA1105_SIZE_CGU_CMD 4
10 struct sja1105_cfg_pad_mii_tx {
11 u64 d32_os;
12 u64 d32_ipud;
13 u64 d10_os;
14 u64 d10_ipud;
15 u64 ctrl_os;
16 u64 ctrl_ipud;
17 u64 clk_os;
18 u64 clk_ih;
19 u64 clk_ipud;
22 /* UM10944 Table 82.
23 * IDIV_0_C to IDIV_4_C control registers
24 * (addr. 10000Bh to 10000Fh)
26 struct sja1105_cgu_idiv {
27 u64 clksrc;
28 u64 autoblock;
29 u64 idiv;
30 u64 pd;
33 /* PLL_1_C control register
35 * SJA1105 E/T: UM10944 Table 81 (address 10000Ah)
36 * SJA1105 P/Q/R/S: UM11040 Table 116 (address 10000Ah)
38 struct sja1105_cgu_pll_ctrl {
39 u64 pllclksrc;
40 u64 msel;
41 u64 autoblock;
42 u64 psel;
43 u64 direct;
44 u64 fbsel;
45 u64 bypass;
46 u64 pd;
49 enum {
50 CLKSRC_MII0_TX_CLK = 0x00,
51 CLKSRC_MII0_RX_CLK = 0x01,
52 CLKSRC_MII1_TX_CLK = 0x02,
53 CLKSRC_MII1_RX_CLK = 0x03,
54 CLKSRC_MII2_TX_CLK = 0x04,
55 CLKSRC_MII2_RX_CLK = 0x05,
56 CLKSRC_MII3_TX_CLK = 0x06,
57 CLKSRC_MII3_RX_CLK = 0x07,
58 CLKSRC_MII4_TX_CLK = 0x08,
59 CLKSRC_MII4_RX_CLK = 0x09,
60 CLKSRC_PLL0 = 0x0B,
61 CLKSRC_PLL1 = 0x0E,
62 CLKSRC_IDIV0 = 0x11,
63 CLKSRC_IDIV1 = 0x12,
64 CLKSRC_IDIV2 = 0x13,
65 CLKSRC_IDIV3 = 0x14,
66 CLKSRC_IDIV4 = 0x15,
69 /* UM10944 Table 83.
70 * MIIx clock control registers 1 to 30
71 * (addresses 100013h to 100035h)
73 struct sja1105_cgu_mii_ctrl {
74 u64 clksrc;
75 u64 autoblock;
76 u64 pd;
79 static void sja1105_cgu_idiv_packing(void *buf, struct sja1105_cgu_idiv *idiv,
80 enum packing_op op)
82 const int size = 4;
84 sja1105_packing(buf, &idiv->clksrc, 28, 24, size, op);
85 sja1105_packing(buf, &idiv->autoblock, 11, 11, size, op);
86 sja1105_packing(buf, &idiv->idiv, 5, 2, size, op);
87 sja1105_packing(buf, &idiv->pd, 0, 0, size, op);
90 static int sja1105_cgu_idiv_config(struct sja1105_private *priv, int port,
91 bool enabled, int factor)
93 const struct sja1105_regs *regs = priv->info->regs;
94 struct device *dev = priv->ds->dev;
95 struct sja1105_cgu_idiv idiv;
96 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
98 if (enabled && factor != 1 && factor != 10) {
99 dev_err(dev, "idiv factor must be 1 or 10\n");
100 return -ERANGE;
103 /* Payload for packed_buf */
104 idiv.clksrc = 0x0A; /* 25MHz */
105 idiv.autoblock = 1; /* Block clk automatically */
106 idiv.idiv = factor - 1; /* Divide by 1 or 10 */
107 idiv.pd = enabled ? 0 : 1; /* Power down? */
108 sja1105_cgu_idiv_packing(packed_buf, &idiv, PACK);
110 return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
111 regs->cgu_idiv[port], packed_buf,
112 SJA1105_SIZE_CGU_CMD);
115 static void
116 sja1105_cgu_mii_control_packing(void *buf, struct sja1105_cgu_mii_ctrl *cmd,
117 enum packing_op op)
119 const int size = 4;
121 sja1105_packing(buf, &cmd->clksrc, 28, 24, size, op);
122 sja1105_packing(buf, &cmd->autoblock, 11, 11, size, op);
123 sja1105_packing(buf, &cmd->pd, 0, 0, size, op);
126 static int sja1105_cgu_mii_tx_clk_config(struct sja1105_private *priv,
127 int port, sja1105_mii_role_t role)
129 const struct sja1105_regs *regs = priv->info->regs;
130 struct sja1105_cgu_mii_ctrl mii_tx_clk;
131 const int mac_clk_sources[] = {
132 CLKSRC_MII0_TX_CLK,
133 CLKSRC_MII1_TX_CLK,
134 CLKSRC_MII2_TX_CLK,
135 CLKSRC_MII3_TX_CLK,
136 CLKSRC_MII4_TX_CLK,
138 const int phy_clk_sources[] = {
139 CLKSRC_IDIV0,
140 CLKSRC_IDIV1,
141 CLKSRC_IDIV2,
142 CLKSRC_IDIV3,
143 CLKSRC_IDIV4,
145 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
146 int clksrc;
148 if (role == XMII_MAC)
149 clksrc = mac_clk_sources[port];
150 else
151 clksrc = phy_clk_sources[port];
153 /* Payload for packed_buf */
154 mii_tx_clk.clksrc = clksrc;
155 mii_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
156 mii_tx_clk.pd = 0; /* Power Down off => enabled */
157 sja1105_cgu_mii_control_packing(packed_buf, &mii_tx_clk, PACK);
159 return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
160 regs->mii_tx_clk[port], packed_buf,
161 SJA1105_SIZE_CGU_CMD);
164 static int
165 sja1105_cgu_mii_rx_clk_config(struct sja1105_private *priv, int port)
167 const struct sja1105_regs *regs = priv->info->regs;
168 struct sja1105_cgu_mii_ctrl mii_rx_clk;
169 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
170 const int clk_sources[] = {
171 CLKSRC_MII0_RX_CLK,
172 CLKSRC_MII1_RX_CLK,
173 CLKSRC_MII2_RX_CLK,
174 CLKSRC_MII3_RX_CLK,
175 CLKSRC_MII4_RX_CLK,
178 /* Payload for packed_buf */
179 mii_rx_clk.clksrc = clk_sources[port];
180 mii_rx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
181 mii_rx_clk.pd = 0; /* Power Down off => enabled */
182 sja1105_cgu_mii_control_packing(packed_buf, &mii_rx_clk, PACK);
184 return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
185 regs->mii_rx_clk[port], packed_buf,
186 SJA1105_SIZE_CGU_CMD);
189 static int
190 sja1105_cgu_mii_ext_tx_clk_config(struct sja1105_private *priv, int port)
192 const struct sja1105_regs *regs = priv->info->regs;
193 struct sja1105_cgu_mii_ctrl mii_ext_tx_clk;
194 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
195 const int clk_sources[] = {
196 CLKSRC_IDIV0,
197 CLKSRC_IDIV1,
198 CLKSRC_IDIV2,
199 CLKSRC_IDIV3,
200 CLKSRC_IDIV4,
203 /* Payload for packed_buf */
204 mii_ext_tx_clk.clksrc = clk_sources[port];
205 mii_ext_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
206 mii_ext_tx_clk.pd = 0; /* Power Down off => enabled */
207 sja1105_cgu_mii_control_packing(packed_buf, &mii_ext_tx_clk, PACK);
209 return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
210 regs->mii_ext_tx_clk[port],
211 packed_buf, SJA1105_SIZE_CGU_CMD);
214 static int
215 sja1105_cgu_mii_ext_rx_clk_config(struct sja1105_private *priv, int port)
217 const struct sja1105_regs *regs = priv->info->regs;
218 struct sja1105_cgu_mii_ctrl mii_ext_rx_clk;
219 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
220 const int clk_sources[] = {
221 CLKSRC_IDIV0,
222 CLKSRC_IDIV1,
223 CLKSRC_IDIV2,
224 CLKSRC_IDIV3,
225 CLKSRC_IDIV4,
228 /* Payload for packed_buf */
229 mii_ext_rx_clk.clksrc = clk_sources[port];
230 mii_ext_rx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
231 mii_ext_rx_clk.pd = 0; /* Power Down off => enabled */
232 sja1105_cgu_mii_control_packing(packed_buf, &mii_ext_rx_clk, PACK);
234 return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
235 regs->mii_ext_rx_clk[port],
236 packed_buf, SJA1105_SIZE_CGU_CMD);
239 static int sja1105_mii_clocking_setup(struct sja1105_private *priv, int port,
240 sja1105_mii_role_t role)
242 struct device *dev = priv->ds->dev;
243 int rc;
245 dev_dbg(dev, "Configuring MII-%s clocking\n",
246 (role == XMII_MAC) ? "MAC" : "PHY");
247 /* If role is MAC, disable IDIV
248 * If role is PHY, enable IDIV and configure for 1/1 divider
250 rc = sja1105_cgu_idiv_config(priv, port, (role == XMII_PHY), 1);
251 if (rc < 0)
252 return rc;
254 /* Configure CLKSRC of MII_TX_CLK_n
255 * * If role is MAC, select TX_CLK_n
256 * * If role is PHY, select IDIV_n
258 rc = sja1105_cgu_mii_tx_clk_config(priv, port, role);
259 if (rc < 0)
260 return rc;
262 /* Configure CLKSRC of MII_RX_CLK_n
263 * Select RX_CLK_n
265 rc = sja1105_cgu_mii_rx_clk_config(priv, port);
266 if (rc < 0)
267 return rc;
269 if (role == XMII_PHY) {
270 /* Per MII spec, the PHY (which is us) drives the TX_CLK pin */
272 /* Configure CLKSRC of EXT_TX_CLK_n
273 * Select IDIV_n
275 rc = sja1105_cgu_mii_ext_tx_clk_config(priv, port);
276 if (rc < 0)
277 return rc;
279 /* Configure CLKSRC of EXT_RX_CLK_n
280 * Select IDIV_n
282 rc = sja1105_cgu_mii_ext_rx_clk_config(priv, port);
283 if (rc < 0)
284 return rc;
286 return 0;
289 static void
290 sja1105_cgu_pll_control_packing(void *buf, struct sja1105_cgu_pll_ctrl *cmd,
291 enum packing_op op)
293 const int size = 4;
295 sja1105_packing(buf, &cmd->pllclksrc, 28, 24, size, op);
296 sja1105_packing(buf, &cmd->msel, 23, 16, size, op);
297 sja1105_packing(buf, &cmd->autoblock, 11, 11, size, op);
298 sja1105_packing(buf, &cmd->psel, 9, 8, size, op);
299 sja1105_packing(buf, &cmd->direct, 7, 7, size, op);
300 sja1105_packing(buf, &cmd->fbsel, 6, 6, size, op);
301 sja1105_packing(buf, &cmd->bypass, 1, 1, size, op);
302 sja1105_packing(buf, &cmd->pd, 0, 0, size, op);
305 static int sja1105_cgu_rgmii_tx_clk_config(struct sja1105_private *priv,
306 int port, sja1105_speed_t speed)
308 const struct sja1105_regs *regs = priv->info->regs;
309 struct sja1105_cgu_mii_ctrl txc;
310 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
311 int clksrc;
313 if (speed == SJA1105_SPEED_1000MBPS) {
314 clksrc = CLKSRC_PLL0;
315 } else {
316 int clk_sources[] = {CLKSRC_IDIV0, CLKSRC_IDIV1, CLKSRC_IDIV2,
317 CLKSRC_IDIV3, CLKSRC_IDIV4};
318 clksrc = clk_sources[port];
321 /* RGMII: 125MHz for 1000, 25MHz for 100, 2.5MHz for 10 */
322 txc.clksrc = clksrc;
323 /* Autoblock clk while changing clksrc */
324 txc.autoblock = 1;
325 /* Power Down off => enabled */
326 txc.pd = 0;
327 sja1105_cgu_mii_control_packing(packed_buf, &txc, PACK);
329 return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
330 regs->rgmii_tx_clk[port],
331 packed_buf, SJA1105_SIZE_CGU_CMD);
334 /* AGU */
335 static void
336 sja1105_cfg_pad_mii_tx_packing(void *buf, struct sja1105_cfg_pad_mii_tx *cmd,
337 enum packing_op op)
339 const int size = 4;
341 sja1105_packing(buf, &cmd->d32_os, 28, 27, size, op);
342 sja1105_packing(buf, &cmd->d32_ipud, 25, 24, size, op);
343 sja1105_packing(buf, &cmd->d10_os, 20, 19, size, op);
344 sja1105_packing(buf, &cmd->d10_ipud, 17, 16, size, op);
345 sja1105_packing(buf, &cmd->ctrl_os, 12, 11, size, op);
346 sja1105_packing(buf, &cmd->ctrl_ipud, 9, 8, size, op);
347 sja1105_packing(buf, &cmd->clk_os, 4, 3, size, op);
348 sja1105_packing(buf, &cmd->clk_ih, 2, 2, size, op);
349 sja1105_packing(buf, &cmd->clk_ipud, 1, 0, size, op);
352 static int sja1105_rgmii_cfg_pad_tx_config(struct sja1105_private *priv,
353 int port)
355 const struct sja1105_regs *regs = priv->info->regs;
356 struct sja1105_cfg_pad_mii_tx pad_mii_tx;
357 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
359 /* Payload */
360 pad_mii_tx.d32_os = 3; /* TXD[3:2] output stage: */
361 /* high noise/high speed */
362 pad_mii_tx.d10_os = 3; /* TXD[1:0] output stage: */
363 /* high noise/high speed */
364 pad_mii_tx.d32_ipud = 2; /* TXD[3:2] input stage: */
365 /* plain input (default) */
366 pad_mii_tx.d10_ipud = 2; /* TXD[1:0] input stage: */
367 /* plain input (default) */
368 pad_mii_tx.ctrl_os = 3; /* TX_CTL / TX_ER output stage */
369 pad_mii_tx.ctrl_ipud = 2; /* TX_CTL / TX_ER input stage (default) */
370 pad_mii_tx.clk_os = 3; /* TX_CLK output stage */
371 pad_mii_tx.clk_ih = 0; /* TX_CLK input hysteresis (default) */
372 pad_mii_tx.clk_ipud = 2; /* TX_CLK input stage (default) */
373 sja1105_cfg_pad_mii_tx_packing(packed_buf, &pad_mii_tx, PACK);
375 return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
376 regs->rgmii_pad_mii_tx[port],
377 packed_buf, SJA1105_SIZE_CGU_CMD);
380 static int sja1105_rgmii_clocking_setup(struct sja1105_private *priv, int port)
382 struct device *dev = priv->ds->dev;
383 struct sja1105_mac_config_entry *mac;
384 sja1105_speed_t speed;
385 int rc;
387 mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
388 speed = mac[port].speed;
390 dev_dbg(dev, "Configuring port %d RGMII at speed %dMbps\n",
391 port, speed);
393 switch (speed) {
394 case SJA1105_SPEED_1000MBPS:
395 /* 1000Mbps, IDIV disabled (125 MHz) */
396 rc = sja1105_cgu_idiv_config(priv, port, false, 1);
397 break;
398 case SJA1105_SPEED_100MBPS:
399 /* 100Mbps, IDIV enabled, divide by 1 (25 MHz) */
400 rc = sja1105_cgu_idiv_config(priv, port, true, 1);
401 break;
402 case SJA1105_SPEED_10MBPS:
403 /* 10Mbps, IDIV enabled, divide by 10 (2.5 MHz) */
404 rc = sja1105_cgu_idiv_config(priv, port, true, 10);
405 break;
406 case SJA1105_SPEED_AUTO:
407 /* Skip CGU configuration if there is no speed available
408 * (e.g. link is not established yet)
410 dev_dbg(dev, "Speed not available, skipping CGU config\n");
411 return 0;
412 default:
413 rc = -EINVAL;
416 if (rc < 0) {
417 dev_err(dev, "Failed to configure idiv\n");
418 return rc;
420 rc = sja1105_cgu_rgmii_tx_clk_config(priv, port, speed);
421 if (rc < 0) {
422 dev_err(dev, "Failed to configure RGMII Tx clock\n");
423 return rc;
425 rc = sja1105_rgmii_cfg_pad_tx_config(priv, port);
426 if (rc < 0) {
427 dev_err(dev, "Failed to configure Tx pad registers\n");
428 return rc;
430 if (!priv->info->setup_rgmii_delay)
431 return 0;
433 return priv->info->setup_rgmii_delay(priv, port);
436 static int sja1105_cgu_rmii_ref_clk_config(struct sja1105_private *priv,
437 int port)
439 const struct sja1105_regs *regs = priv->info->regs;
440 struct sja1105_cgu_mii_ctrl ref_clk;
441 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
442 const int clk_sources[] = {
443 CLKSRC_MII0_TX_CLK,
444 CLKSRC_MII1_TX_CLK,
445 CLKSRC_MII2_TX_CLK,
446 CLKSRC_MII3_TX_CLK,
447 CLKSRC_MII4_TX_CLK,
450 /* Payload for packed_buf */
451 ref_clk.clksrc = clk_sources[port];
452 ref_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
453 ref_clk.pd = 0; /* Power Down off => enabled */
454 sja1105_cgu_mii_control_packing(packed_buf, &ref_clk, PACK);
456 return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
457 regs->rmii_ref_clk[port],
458 packed_buf, SJA1105_SIZE_CGU_CMD);
461 static int
462 sja1105_cgu_rmii_ext_tx_clk_config(struct sja1105_private *priv, int port)
464 const struct sja1105_regs *regs = priv->info->regs;
465 struct sja1105_cgu_mii_ctrl ext_tx_clk;
466 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
468 /* Payload for packed_buf */
469 ext_tx_clk.clksrc = CLKSRC_PLL1;
470 ext_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
471 ext_tx_clk.pd = 0; /* Power Down off => enabled */
472 sja1105_cgu_mii_control_packing(packed_buf, &ext_tx_clk, PACK);
474 return sja1105_spi_send_packed_buf(priv, SPI_WRITE,
475 regs->rmii_ext_tx_clk[port],
476 packed_buf, SJA1105_SIZE_CGU_CMD);
479 static int sja1105_cgu_rmii_pll_config(struct sja1105_private *priv)
481 const struct sja1105_regs *regs = priv->info->regs;
482 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
483 struct sja1105_cgu_pll_ctrl pll = {0};
484 struct device *dev = priv->ds->dev;
485 int rc;
487 /* PLL1 must be enabled and output 50 Mhz.
488 * This is done by writing first 0x0A010941 to
489 * the PLL_1_C register and then deasserting
490 * power down (PD) 0x0A010940.
493 /* Step 1: PLL1 setup for 50Mhz */
494 pll.pllclksrc = 0xA;
495 pll.msel = 0x1;
496 pll.autoblock = 0x1;
497 pll.psel = 0x1;
498 pll.direct = 0x0;
499 pll.fbsel = 0x1;
500 pll.bypass = 0x0;
501 pll.pd = 0x1;
503 sja1105_cgu_pll_control_packing(packed_buf, &pll, PACK);
504 rc = sja1105_spi_send_packed_buf(priv, SPI_WRITE, regs->rmii_pll1,
505 packed_buf, SJA1105_SIZE_CGU_CMD);
506 if (rc < 0) {
507 dev_err(dev, "failed to configure PLL1 for 50MHz\n");
508 return rc;
511 /* Step 2: Enable PLL1 */
512 pll.pd = 0x0;
514 sja1105_cgu_pll_control_packing(packed_buf, &pll, PACK);
515 rc = sja1105_spi_send_packed_buf(priv, SPI_WRITE, regs->rmii_pll1,
516 packed_buf, SJA1105_SIZE_CGU_CMD);
517 if (rc < 0) {
518 dev_err(dev, "failed to enable PLL1\n");
519 return rc;
521 return rc;
524 static int sja1105_rmii_clocking_setup(struct sja1105_private *priv, int port,
525 sja1105_mii_role_t role)
527 struct device *dev = priv->ds->dev;
528 int rc;
530 dev_dbg(dev, "Configuring RMII-%s clocking\n",
531 (role == XMII_MAC) ? "MAC" : "PHY");
532 /* AH1601.pdf chapter 2.5.1. Sources */
533 if (role == XMII_MAC) {
534 /* Configure and enable PLL1 for 50Mhz output */
535 rc = sja1105_cgu_rmii_pll_config(priv);
536 if (rc < 0)
537 return rc;
539 /* Disable IDIV for this port */
540 rc = sja1105_cgu_idiv_config(priv, port, false, 1);
541 if (rc < 0)
542 return rc;
543 /* Source to sink mappings */
544 rc = sja1105_cgu_rmii_ref_clk_config(priv, port);
545 if (rc < 0)
546 return rc;
547 if (role == XMII_MAC) {
548 rc = sja1105_cgu_rmii_ext_tx_clk_config(priv, port);
549 if (rc < 0)
550 return rc;
552 return 0;
555 int sja1105_clocking_setup_port(struct sja1105_private *priv, int port)
557 struct sja1105_xmii_params_entry *mii;
558 struct device *dev = priv->ds->dev;
559 sja1105_phy_interface_t phy_mode;
560 sja1105_mii_role_t role;
561 int rc;
563 mii = priv->static_config.tables[BLK_IDX_XMII_PARAMS].entries;
565 /* RGMII etc */
566 phy_mode = mii->xmii_mode[port];
567 /* MAC or PHY, for applicable types (not RGMII) */
568 role = mii->phy_mac[port];
570 switch (phy_mode) {
571 case XMII_MODE_MII:
572 rc = sja1105_mii_clocking_setup(priv, port, role);
573 break;
574 case XMII_MODE_RMII:
575 rc = sja1105_rmii_clocking_setup(priv, port, role);
576 break;
577 case XMII_MODE_RGMII:
578 rc = sja1105_rgmii_clocking_setup(priv, port);
579 break;
580 default:
581 dev_err(dev, "Invalid interface mode specified: %d\n",
582 phy_mode);
583 return -EINVAL;
585 if (rc)
586 dev_err(dev, "Clocking setup for port %d failed: %d\n",
587 port, rc);
588 return rc;
591 int sja1105_clocking_setup(struct sja1105_private *priv)
593 int port, rc;
595 for (port = 0; port < SJA1105_NUM_PORTS; port++) {
596 rc = sja1105_clocking_setup_port(priv, port);
597 if (rc < 0)
598 return rc;
600 return 0;