aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/phy
diff options
context:
space:
mode:
authorLee Jones <lee.jones@linaro.org>2014-07-09 07:41:13 -0400
committerKishon Vijay Abraham I <kishon@ti.com>2014-07-22 03:16:43 -0400
commit7ebdb52e192c4d496a9b3a87d47eba3eba3e1fd4 (patch)
tree347ff06a4e07e16f73a1e0f56912961ee51670b1 /drivers/phy
parent6e877fedb1cff0f4a0988d30418ad87abaefafcb (diff)
phy: miphy365x: Represent each PHY channel as a DT subnode
This has the added advantages of being able to enable/disable each of the channels as simply as enabling/disabling the DT node. Suggested-by: Kishon Vijay Abraham I <kishon@ti.com> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Diffstat (limited to 'drivers/phy')
-rw-r--r--drivers/phy/phy-miphy365x.c256
1 files changed, 138 insertions, 118 deletions
diff --git a/drivers/phy/phy-miphy365x.c b/drivers/phy/phy-miphy365x.c
index 65ecd04da9bc..e111baf187ce 100644
--- a/drivers/phy/phy-miphy365x.c
+++ b/drivers/phy/phy-miphy365x.c
@@ -18,6 +18,7 @@
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/of_platform.h> 20#include <linux/of_platform.h>
21#include <linux/of_address.h>
21#include <linux/clk.h> 22#include <linux/clk.h>
22#include <linux/phy/phy.h> 23#include <linux/phy/phy.h>
23#include <linux/delay.h> 24#include <linux/delay.h>
@@ -28,10 +29,8 @@
28 29
29#define HFC_TIMEOUT 100 30#define HFC_TIMEOUT 100
30 31
31#define SYSCFG_2521 0x824 32#define SYSCFG_SELECT_SATA_MASK BIT(1)
32#define SYSCFG_2522 0x828 33#define SYSCFG_SELECT_SATA_POS 1
33#define SYSCFG_PCIE_SATA_MASK BIT(1)
34#define SYSCFG_PCIE_SATA_POS 1
35 34
36/* MiPHY365x register definitions */ 35/* MiPHY365x register definitions */
37#define RESET_REG 0x00 36#define RESET_REG 0x00
@@ -136,25 +135,21 @@
136#define BIT_LOCK_LEVEL 0x01 135#define BIT_LOCK_LEVEL 0x01
137#define BIT_LOCK_CNT_512 (0x03 << 5) 136#define BIT_LOCK_CNT_512 (0x03 << 5)
138 137
139static u8 ports[] = { MIPHY_PORT_0, MIPHY_PORT_1 };
140
141struct miphy365x_phy { 138struct miphy365x_phy {
142 struct phy *phy; 139 struct phy *phy;
143 void __iomem *base; 140 void __iomem *base;
144 void __iomem *sata; 141 bool pcie_tx_pol_inv;
145 void __iomem *pcie; 142 bool sata_tx_pol_inv;
143 u32 sata_gen;
144 u64 ctrlreg;
146 u8 type; 145 u8 type;
147 u8 port;
148}; 146};
149 147
150struct miphy365x_dev { 148struct miphy365x_dev {
151 struct device *dev; 149 struct device *dev;
152 struct regmap *regmap; 150 struct regmap *regmap;
153 struct mutex miphy_mutex; 151 struct mutex miphy_mutex;
154 struct miphy365x phys[ARRAY_SIZE(ports)]; 152 struct miphy365x_phy **phys;
155 bool pcie_tx_pol_inv;
156 bool sata_tx_pol_inv;
157 u32 sata_gen;
158}; 153};
159 154
160/* 155/*
@@ -180,27 +175,12 @@ static u8 rx_tx_spd[] = {
180static int miphy365x_set_path(struct miphy365x_phy *miphy_phy, 175static int miphy365x_set_path(struct miphy365x_phy *miphy_phy,
181 struct miphy365x_dev *miphy_dev) 176 struct miphy365x_dev *miphy_dev)
182{ 177{
183 u8 config = miphy_phy->type | miphy_phy->port; 178 bool sata = (miphy_phy->type == MIPHY_TYPE_SATA);
184 u32 mask = SYSCFG_PCIE_SATA_MASK;
185 u32 reg;
186 bool sata;
187
188 switch (config) {
189 case MIPHY_SATA_PORT0:
190 reg = SYSCFG_2521;
191 sata = true;
192 break;
193 case MIPHY_PCIE_PORT1:
194 reg = SYSCFG_2522;
195 sata = false;
196 break;
197 default:
198 dev_err(miphy_dev->dev, "Configuration not supported\n");
199 return -EINVAL;
200 }
201 179
202 return regmap_update_bits(miphy_dev->regmap, reg, mask, 180 return regmap_update_bits(miphy_dev->regmap,
203 sata << SYSCFG_PCIE_SATA_POS); 181 (unsigned int)miphy_phy->ctrlreg,
182 SYSCFG_SELECT_SATA_MASK,
183 sata << SYSCFG_SELECT_SATA_POS);
204} 184}
205 185
206static int miphy365x_init_pcie_port(struct miphy365x_phy *miphy_phy, 186static int miphy365x_init_pcie_port(struct miphy365x_phy *miphy_phy,
@@ -261,14 +241,14 @@ static inline void miphy365x_set_comp(struct miphy365x_phy *miphy_phy,
261{ 241{
262 u8 val, mask; 242 u8 val, mask;
263 243
264 if (miphy_dev->sata_gen == SATA_GEN1) 244 if (miphy_phy->sata_gen == SATA_GEN1)
265 writeb_relaxed(COMP_2MHZ_RAT_GEN1, 245 writeb_relaxed(COMP_2MHZ_RAT_GEN1,
266 miphy_phy->base + COMP_CTRL2_REG); 246 miphy_phy->base + COMP_CTRL2_REG);
267 else 247 else
268 writeb_relaxed(COMP_2MHZ_RAT, 248 writeb_relaxed(COMP_2MHZ_RAT,
269 miphy_phy->base + COMP_CTRL2_REG); 249 miphy_phy->base + COMP_CTRL2_REG);
270 250
271 if (miphy_dev->sata_gen != SATA_GEN3) { 251 if (miphy_phy->sata_gen != SATA_GEN3) {
272 writeb_relaxed(COMSR_COMP_REF, 252 writeb_relaxed(COMSR_COMP_REF,
273 miphy_phy->base + COMP_CTRL3_REG); 253 miphy_phy->base + COMP_CTRL3_REG);
274 /* 254 /*
@@ -312,7 +292,7 @@ static inline void miphy365x_set_ssc(struct miphy365x_phy *miphy_phy,
312 miphy_phy->base + PLL_SSC_PER_LSB_REG); 292 miphy_phy->base + PLL_SSC_PER_LSB_REG);
313 293
314 /* SSC Settings complete */ 294 /* SSC Settings complete */
315 if (miphy_dev->sata_gen == SATA_GEN1) { 295 if (miphy_phy->sata_gen == SATA_GEN1) {
316 val = PLL_START_CAL | BUF_EN | SYNCHRO_TX | CONFIG_PLL; 296 val = PLL_START_CAL | BUF_EN | SYNCHRO_TX | CONFIG_PLL;
317 writeb_relaxed(val, miphy_phy->base + PLL_CTRL1_REG); 297 writeb_relaxed(val, miphy_phy->base + PLL_CTRL1_REG);
318 } else { 298 } else {
@@ -334,7 +314,7 @@ static int miphy365x_init_sata_port(struct miphy365x_phy *miphy_phy,
334 val = RST_PLL | RST_PLL_CAL | RST_RX | RST_MACRO; 314 val = RST_PLL | RST_PLL_CAL | RST_RX | RST_MACRO;
335 writeb_relaxed(val, miphy_phy->base + RESET_REG); 315 writeb_relaxed(val, miphy_phy->base + RESET_REG);
336 316
337 if (miphy_dev->sata_tx_pol_inv) 317 if (miphy_phy->sata_tx_pol_inv)
338 writeb_relaxed(TX_POL, miphy_phy->base + CTRL_REG); 318 writeb_relaxed(TX_POL, miphy_phy->base + CTRL_REG);
339 319
340 /* 320 /*
@@ -344,7 +324,7 @@ static int miphy365x_init_sata_port(struct miphy365x_phy *miphy_phy,
344 */ 324 */
345 writeb_relaxed(SPDSEL_SEL, miphy_phy->base + BOUNDARY1_REG); 325 writeb_relaxed(SPDSEL_SEL, miphy_phy->base + BOUNDARY1_REG);
346 writeb_relaxed(START_CLK_HF, miphy_phy->base + IDLL_TEST_REG); 326 writeb_relaxed(START_CLK_HF, miphy_phy->base + IDLL_TEST_REG);
347 val = rx_tx_spd[miphy_dev->sata_gen]; 327 val = rx_tx_spd[miphy_phy->sata_gen];
348 writeb_relaxed(val, miphy_phy->base + BOUNDARY3_REG); 328 writeb_relaxed(val, miphy_phy->base + BOUNDARY3_REG);
349 329
350 /* Wait for HFC_READY = 0 */ 330 /* Wait for HFC_READY = 0 */
@@ -355,7 +335,7 @@ static int miphy365x_init_sata_port(struct miphy365x_phy *miphy_phy,
355 /* Compensation Recalibration */ 335 /* Compensation Recalibration */
356 miphy365x_set_comp(miphy_phy, miphy_dev); 336 miphy365x_set_comp(miphy_phy, miphy_dev);
357 337
358 switch (miphy_dev->sata_gen) { 338 switch (miphy_phy->sata_gen) {
359 case SATA_GEN3: 339 case SATA_GEN3:
360 /* 340 /*
361 * TX Swing target 550-600mv peak to peak diff 341 * TX Swing target 550-600mv peak to peak diff
@@ -423,7 +403,7 @@ static int miphy365x_init_sata_port(struct miphy365x_phy *miphy_phy,
423 writeb_relaxed(0x00, miphy_phy->base + BOUNDARY1_REG); 403 writeb_relaxed(0x00, miphy_phy->base + BOUNDARY1_REG);
424 writeb_relaxed(0x00, miphy_phy->base + IDLL_TEST_REG); 404 writeb_relaxed(0x00, miphy_phy->base + IDLL_TEST_REG);
425 writeb_relaxed(RST_RX, miphy_phy->base + RESET_REG); 405 writeb_relaxed(RST_RX, miphy_phy->base + RESET_REG);
426 val = miphy_dev->sata_tx_pol_inv ? 406 val = miphy_phy->sata_tx_pol_inv ?
427 (TX_POL | DES_BIT_LOCK_EN) : DES_BIT_LOCK_EN; 407 (TX_POL | DES_BIT_LOCK_EN) : DES_BIT_LOCK_EN;
428 writeb_relaxed(val, miphy_phy->base + CTRL_REG); 408 writeb_relaxed(val, miphy_phy->base + CTRL_REG);
429 409
@@ -459,40 +439,95 @@ static int miphy365x_init(struct phy *phy)
459 return ret; 439 return ret;
460} 440}
461 441
442int miphy365x_get_addr(struct device *dev, struct miphy365x_phy *miphy_phy,
443 int index)
444{
445 struct device_node *phynode = miphy_phy->phy->dev.of_node;
446 const char *name;
447 const __be32 *taddr;
448 int type = miphy_phy->type;
449 int ret;
450
451 ret = of_property_read_string_index(phynode, "reg-names", index, &name);
452 if (ret) {
453 dev_err(dev, "no reg-names property not found\n");
454 return ret;
455 }
456
457 if (!strncmp(name, "syscfg", 6)) {
458 taddr = of_get_address(phynode, index, NULL, NULL);
459 if (!taddr) {
460 dev_err(dev, "failed to fetch syscfg address\n");
461 return -EINVAL;
462 }
463
464 miphy_phy->ctrlreg = of_translate_address(phynode, taddr);
465 if (miphy_phy->ctrlreg == OF_BAD_ADDR) {
466 dev_err(dev, "failed to translate syscfg address\n");
467 return -EINVAL;
468 }
469
470 return 0;
471 }
472
473 if (!((!strncmp(name, "sata", 4) && type == MIPHY_TYPE_SATA) ||
474 (!strncmp(name, "pcie", 4) && type == MIPHY_TYPE_PCIE)))
475 return 0;
476
477 miphy_phy->base = of_iomap(phynode, index);
478 if (!miphy_phy->base) {
479 dev_err(dev, "Failed to map %s\n", phynode->full_name);
480 return -EINVAL;
481 }
482
483 return 0;
484}
485
462static struct phy *miphy365x_xlate(struct device *dev, 486static struct phy *miphy365x_xlate(struct device *dev,
463 struct of_phandle_args *args) 487 struct of_phandle_args *args)
464{ 488{
465 struct miphy365x_dev *state = dev_get_drvdata(dev); 489 struct miphy365x_dev *miphy_dev = dev_get_drvdata(dev);
466 u8 port, type; 490 struct miphy365x_phy *miphy_phy = NULL;
491 struct device_node *phynode = args->np;
492 int ret, index;
493
494 if (!of_device_is_available(phynode)) {
495 dev_warn(dev, "Requested PHY is disabled\n");
496 return ERR_PTR(-ENODEV);
497 }
467 498
468 if (args->count != 2) { 499 if (args->args_count != 1) {
469 dev_err(dev, "Invalid number of cells in 'phy' property\n"); 500 dev_err(dev, "Invalid number of cells in 'phy' property\n");
470 return ERR_PTR(-EINVAL); 501 return ERR_PTR(-EINVAL);
471 } 502 }
472 503
473 if (args->args[0] & 0xFFFFFF00 || args->args[1] & 0xFFFFFF00) { 504 for (index = 0; index < of_get_child_count(dev->of_node); index++)
474 dev_err(dev, "Unsupported flags set in 'phy' property\n"); 505 if (phynode == miphy_dev->phys[index]->phy->dev.of_node) {
506 miphy_phy = miphy_dev->phys[index];
507 break;
508 }
509
510 if (!miphy_phy) {
511 dev_err(dev, "Failed to find appropriate phy\n");
475 return ERR_PTR(-EINVAL); 512 return ERR_PTR(-EINVAL);
476 } 513 }
477 514
478 port = args->args[0]; 515 miphy_phy->type = args->args[0];
479 type = args->args[1];
480
481 if (WARN_ON(port >= ARRAY_SIZE(ports)))
482 return ERR_PTR(-EINVAL);
483 516
484 if (type == MIPHY_TYPE_SATA) 517 if (!(miphy_phy->type == MIPHY_TYPE_SATA ||
485 state->phys[port].base = state->phys[port].sata; 518 miphy_phy->type == MIPHY_TYPE_PCIE)) {
486 else if (type == MIPHY_TYPE_PCIE) 519 dev_err(dev, "Unsupported device type: %d\n", miphy_phy->type);
487 state->phys[port].base = state->phys[port].pcie;
488 else {
489 WARN(1, "Invalid type specified in DT");
490 return ERR_PTR(-EINVAL); 520 return ERR_PTR(-EINVAL);
491 } 521 }
492 522
493 state->phys[port].type = type; 523 /* Each port handles SATA and PCIE - third entry is always sysconf. */
524 for (index = 0; index < 3; index++) {
525 ret = miphy365x_get_addr(dev, miphy_phy, index);
526 if (ret < 0)
527 return ERR_PTR(ret);
528 }
494 529
495 return state->phys[port].phy; 530 return miphy_phy->phy;
496} 531}
497 532
498static struct phy_ops miphy365x_ops = { 533static struct phy_ops miphy365x_ops = {
@@ -500,95 +535,80 @@ static struct phy_ops miphy365x_ops = {
500 .owner = THIS_MODULE, 535 .owner = THIS_MODULE,
501}; 536};
502 537
503static int miphy365x_get_base_addr(struct platform_device *pdev, 538static int miphy365x_of_probe(struct device_node *phynode,
504 struct miphy365x_phy *phy, u8 port) 539 struct miphy365x_phy *miphy_phy)
505{ 540{
506 struct resource *res; 541 of_property_read_u32(phynode, "st,sata-gen", &miphy_phy->sata_gen);
507 char type[6]; 542 if (!miphy_phy->sata_gen)
543 miphy_phy->sata_gen = SATA_GEN1;
508 544
509 sprintf(type, "sata%d", port); 545 miphy_phy->pcie_tx_pol_inv =
546 of_property_read_bool(phynode, "st,pcie-tx-pol-inv");
510 547
511 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, type); 548 miphy_phy->sata_tx_pol_inv =
512 phy->sata = devm_ioremap_resource(&pdev->dev, res)); 549 of_property_read_bool(phynode, "st,sata-tx-pol-inv");
513 if (!phy->sata)
514 return -ENOMEM;
515
516 sprintf(type, "pcie%d", port);
517
518 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, type);
519 phy->pcie = devm_ioremap_resource(&pdev->dev, res));
520 if (!phy->pcie)
521 return -ENOMEM;
522
523 return 0;
524}
525
526static int miphy365x_of_probe(struct device_node *np,
527 struct miphy365x_dev *phy_dev)
528{
529 phy_dev->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
530 if (IS_ERR(phy_dev->regmap)) {
531 dev_err(phy_dev->dev, "No syscfg phandle specified\n");
532 return PTR_ERR(phy_dev->regmap);
533 }
534
535 of_property_read_u32(np, "st,sata-gen", &phy_dev->sata_gen);
536 if (!phy_dev->sata_gen)
537 phy_dev->sata_gen = SATA_GEN1;
538
539 phy_dev->pcie_tx_pol_inv =
540 of_property_read_bool(np, "st,pcie-tx-pol-inv");
541
542 phy_dev->sata_tx_pol_inv =
543 of_property_read_bool(np, "st,sata-tx-pol-inv");
544 550
545 return 0; 551 return 0;
546} 552}
547 553
548static int miphy365x_probe(struct platform_device *pdev) 554static int miphy365x_probe(struct platform_device *pdev)
549{ 555{
550 struct device_node *np = pdev->dev.of_node; 556 struct device_node *child, *np = pdev->dev.of_node;
551 struct miphy365x_dev *phy_dev; 557 struct miphy365x_dev *miphy_dev;
552 struct device *dev = &pdev->dev;
553 struct phy_provider *provider; 558 struct phy_provider *provider;
554 u8 port; 559 struct phy *phy;
560 int chancount, port = 0;
555 int ret; 561 int ret;
556 562
557 phy_dev = devm_kzalloc(dev, sizeof(*phy_dev), GFP_KERNEL); 563 miphy_dev = devm_kzalloc(&pdev->dev, sizeof(*miphy_dev), GFP_KERNEL);
558 if (!phy_dev) 564 if (!miphy_dev)
559 return -ENOMEM; 565 return -ENOMEM;
560 566
561 ret = miphy365x_of_probe(np, phy_dev); 567 chancount = of_get_child_count(np);
562 if (ret) 568 miphy_dev->phys = devm_kzalloc(&pdev->dev, sizeof(phy) * chancount,
563 return ret; 569 GFP_KERNEL);
570 if (!miphy_dev->phys)
571 return -ENOMEM;
572
573 miphy_dev->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
574 if (IS_ERR(miphy_dev->regmap)) {
575 dev_err(miphy_dev->dev, "No syscfg phandle specified\n");
576 return PTR_ERR(miphy_dev->regmap);
577 }
578
579 miphy_dev->dev = &pdev->dev;
580
581 dev_set_drvdata(&pdev->dev, miphy_dev);
564 582
565 phy_dev->dev = dev; 583 mutex_init(&miphy_dev->miphy_mutex);
566 584
567 dev_set_drvdata(dev, phy_dev); 585 for_each_child_of_node(np, child) {
586 struct miphy365x_phy *miphy_phy;
568 587
569 mutex_init(&phy_dev->miphy_mutex); 588 miphy_phy = devm_kzalloc(&pdev->dev, sizeof(*miphy_phy),
589 GFP_KERNEL);
590 if (!miphy_phy)
591 return -ENOMEM;
570 592
571 for (port = 0; port < ARRAY_SIZE(ports); port++) { 593 miphy_dev->phys[port] = miphy_phy;
572 struct phy *phy;
573 594
574 phy = devm_phy_create(dev, &miphy365x_ops, NULL); 595 phy = devm_phy_create(&pdev->dev, child, &miphy365x_ops, NULL);
575 if (IS_ERR(phy)) { 596 if (IS_ERR(phy)) {
576 dev_err(dev, "failed to create PHY on port %d\n", port); 597 dev_err(&pdev->dev, "failed to create PHY\n");
577 return PTR_ERR(phy); 598 return PTR_ERR(phy);
578 } 599 }
579 600
580 phy_dev->phys[port].phy = phy; 601 miphy_dev->phys[port]->phy = phy;
581 phy_dev->phys[port].port = port;
582 602
583 ret = miphy365x_get_base_addr(pdev, 603 ret = miphy365x_of_probe(child, miphy_phy);
584 &phy_dev->phys[port], port);
585 if (ret) 604 if (ret)
586 return ret; 605 return ret;
587 606
588 phy_set_drvdata(phy, &phy_dev->phys[port]); 607 phy_set_drvdata(phy, miphy_dev->phys[port]);
608 port++;
589 } 609 }
590 610
591 provider = devm_of_phy_provider_register(dev, miphy365x_xlate); 611 provider = devm_of_phy_provider_register(&pdev->dev, miphy365x_xlate);
592 if (IS_ERR(provider)) 612 if (IS_ERR(provider))
593 return PTR_ERR(provider); 613 return PTR_ERR(provider);
594 614