aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/ahci_imx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/ahci_imx.c')
-rw-r--r--drivers/ata/ahci_imx.c187
1 files changed, 176 insertions, 11 deletions
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index cac4360f272a..f3970b4ed889 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -64,6 +64,7 @@ struct imx_ahci_priv {
64 struct regmap *gpr; 64 struct regmap *gpr;
65 bool no_device; 65 bool no_device;
66 bool first_time; 66 bool first_time;
67 u32 phy_params;
67}; 68};
68 69
69static int ahci_imx_hotplug; 70static int ahci_imx_hotplug;
@@ -248,14 +249,7 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv)
248 IMX6Q_GPR13_SATA_TX_LVL_MASK | 249 IMX6Q_GPR13_SATA_TX_LVL_MASK |
249 IMX6Q_GPR13_SATA_MPLL_CLK_EN | 250 IMX6Q_GPR13_SATA_MPLL_CLK_EN |
250 IMX6Q_GPR13_SATA_TX_EDGE_RATE, 251 IMX6Q_GPR13_SATA_TX_EDGE_RATE,
251 IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB | 252 imxpriv->phy_params);
252 IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M |
253 IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F |
254 IMX6Q_GPR13_SATA_SPD_MODE_3P0G |
255 IMX6Q_GPR13_SATA_MPLL_SS_EN |
256 IMX6Q_GPR13_SATA_TX_ATTEN_9_16 |
257 IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB |
258 IMX6Q_GPR13_SATA_TX_LVL_1_025_V);
259 regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, 253 regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
260 IMX6Q_GPR13_SATA_MPLL_CLK_EN, 254 IMX6Q_GPR13_SATA_MPLL_CLK_EN,
261 IMX6Q_GPR13_SATA_MPLL_CLK_EN); 255 IMX6Q_GPR13_SATA_MPLL_CLK_EN);
@@ -265,7 +259,7 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv)
265 ret = imx_sata_phy_reset(hpriv); 259 ret = imx_sata_phy_reset(hpriv);
266 if (ret) { 260 if (ret) {
267 dev_err(dev, "failed to reset phy: %d\n", ret); 261 dev_err(dev, "failed to reset phy: %d\n", ret);
268 goto disable_regulator; 262 goto disable_clk;
269 } 263 }
270 } 264 }
271 265
@@ -273,6 +267,8 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv)
273 267
274 return 0; 268 return 0;
275 269
270disable_clk:
271 clk_disable_unprepare(imxpriv->sata_ref_clk);
276disable_regulator: 272disable_regulator:
277 if (hpriv->target_pwr) 273 if (hpriv->target_pwr)
278 regulator_disable(hpriv->target_pwr); 274 regulator_disable(hpriv->target_pwr);
@@ -369,6 +365,165 @@ static const struct of_device_id imx_ahci_of_match[] = {
369}; 365};
370MODULE_DEVICE_TABLE(of, imx_ahci_of_match); 366MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
371 367
368struct reg_value {
369 u32 of_value;
370 u32 reg_value;
371};
372
373struct reg_property {
374 const char *name;
375 const struct reg_value *values;
376 size_t num_values;
377 u32 def_value;
378 u32 set_value;
379};
380
381static const struct reg_value gpr13_tx_level[] = {
382 { 937, IMX6Q_GPR13_SATA_TX_LVL_0_937_V },
383 { 947, IMX6Q_GPR13_SATA_TX_LVL_0_947_V },
384 { 957, IMX6Q_GPR13_SATA_TX_LVL_0_957_V },
385 { 966, IMX6Q_GPR13_SATA_TX_LVL_0_966_V },
386 { 976, IMX6Q_GPR13_SATA_TX_LVL_0_976_V },
387 { 986, IMX6Q_GPR13_SATA_TX_LVL_0_986_V },
388 { 996, IMX6Q_GPR13_SATA_TX_LVL_0_996_V },
389 { 1005, IMX6Q_GPR13_SATA_TX_LVL_1_005_V },
390 { 1015, IMX6Q_GPR13_SATA_TX_LVL_1_015_V },
391 { 1025, IMX6Q_GPR13_SATA_TX_LVL_1_025_V },
392 { 1035, IMX6Q_GPR13_SATA_TX_LVL_1_035_V },
393 { 1045, IMX6Q_GPR13_SATA_TX_LVL_1_045_V },
394 { 1054, IMX6Q_GPR13_SATA_TX_LVL_1_054_V },
395 { 1064, IMX6Q_GPR13_SATA_TX_LVL_1_064_V },
396 { 1074, IMX6Q_GPR13_SATA_TX_LVL_1_074_V },
397 { 1084, IMX6Q_GPR13_SATA_TX_LVL_1_084_V },
398 { 1094, IMX6Q_GPR13_SATA_TX_LVL_1_094_V },
399 { 1104, IMX6Q_GPR13_SATA_TX_LVL_1_104_V },
400 { 1113, IMX6Q_GPR13_SATA_TX_LVL_1_113_V },
401 { 1123, IMX6Q_GPR13_SATA_TX_LVL_1_123_V },
402 { 1133, IMX6Q_GPR13_SATA_TX_LVL_1_133_V },
403 { 1143, IMX6Q_GPR13_SATA_TX_LVL_1_143_V },
404 { 1152, IMX6Q_GPR13_SATA_TX_LVL_1_152_V },
405 { 1162, IMX6Q_GPR13_SATA_TX_LVL_1_162_V },
406 { 1172, IMX6Q_GPR13_SATA_TX_LVL_1_172_V },
407 { 1182, IMX6Q_GPR13_SATA_TX_LVL_1_182_V },
408 { 1191, IMX6Q_GPR13_SATA_TX_LVL_1_191_V },
409 { 1201, IMX6Q_GPR13_SATA_TX_LVL_1_201_V },
410 { 1211, IMX6Q_GPR13_SATA_TX_LVL_1_211_V },
411 { 1221, IMX6Q_GPR13_SATA_TX_LVL_1_221_V },
412 { 1230, IMX6Q_GPR13_SATA_TX_LVL_1_230_V },
413 { 1240, IMX6Q_GPR13_SATA_TX_LVL_1_240_V }
414};
415
416static const struct reg_value gpr13_tx_boost[] = {
417 { 0, IMX6Q_GPR13_SATA_TX_BOOST_0_00_DB },
418 { 370, IMX6Q_GPR13_SATA_TX_BOOST_0_37_DB },
419 { 740, IMX6Q_GPR13_SATA_TX_BOOST_0_74_DB },
420 { 1110, IMX6Q_GPR13_SATA_TX_BOOST_1_11_DB },
421 { 1480, IMX6Q_GPR13_SATA_TX_BOOST_1_48_DB },
422 { 1850, IMX6Q_GPR13_SATA_TX_BOOST_1_85_DB },
423 { 2220, IMX6Q_GPR13_SATA_TX_BOOST_2_22_DB },
424 { 2590, IMX6Q_GPR13_SATA_TX_BOOST_2_59_DB },
425 { 2960, IMX6Q_GPR13_SATA_TX_BOOST_2_96_DB },
426 { 3330, IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB },
427 { 3700, IMX6Q_GPR13_SATA_TX_BOOST_3_70_DB },
428 { 4070, IMX6Q_GPR13_SATA_TX_BOOST_4_07_DB },
429 { 4440, IMX6Q_GPR13_SATA_TX_BOOST_4_44_DB },
430 { 4810, IMX6Q_GPR13_SATA_TX_BOOST_4_81_DB },
431 { 5280, IMX6Q_GPR13_SATA_TX_BOOST_5_28_DB },
432 { 5750, IMX6Q_GPR13_SATA_TX_BOOST_5_75_DB }
433};
434
435static const struct reg_value gpr13_tx_atten[] = {
436 { 8, IMX6Q_GPR13_SATA_TX_ATTEN_8_16 },
437 { 9, IMX6Q_GPR13_SATA_TX_ATTEN_9_16 },
438 { 10, IMX6Q_GPR13_SATA_TX_ATTEN_10_16 },
439 { 12, IMX6Q_GPR13_SATA_TX_ATTEN_12_16 },
440 { 14, IMX6Q_GPR13_SATA_TX_ATTEN_14_16 },
441 { 16, IMX6Q_GPR13_SATA_TX_ATTEN_16_16 },
442};
443
444static const struct reg_value gpr13_rx_eq[] = {
445 { 500, IMX6Q_GPR13_SATA_RX_EQ_VAL_0_5_DB },
446 { 1000, IMX6Q_GPR13_SATA_RX_EQ_VAL_1_0_DB },
447 { 1500, IMX6Q_GPR13_SATA_RX_EQ_VAL_1_5_DB },
448 { 2000, IMX6Q_GPR13_SATA_RX_EQ_VAL_2_0_DB },
449 { 2500, IMX6Q_GPR13_SATA_RX_EQ_VAL_2_5_DB },
450 { 3000, IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB },
451 { 3500, IMX6Q_GPR13_SATA_RX_EQ_VAL_3_5_DB },
452 { 4000, IMX6Q_GPR13_SATA_RX_EQ_VAL_4_0_DB },
453};
454
455static const struct reg_property gpr13_props[] = {
456 {
457 .name = "fsl,transmit-level-mV",
458 .values = gpr13_tx_level,
459 .num_values = ARRAY_SIZE(gpr13_tx_level),
460 .def_value = IMX6Q_GPR13_SATA_TX_LVL_1_025_V,
461 }, {
462 .name = "fsl,transmit-boost-mdB",
463 .values = gpr13_tx_boost,
464 .num_values = ARRAY_SIZE(gpr13_tx_boost),
465 .def_value = IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB,
466 }, {
467 .name = "fsl,transmit-atten-16ths",
468 .values = gpr13_tx_atten,
469 .num_values = ARRAY_SIZE(gpr13_tx_atten),
470 .def_value = IMX6Q_GPR13_SATA_TX_ATTEN_9_16,
471 }, {
472 .name = "fsl,receive-eq-mdB",
473 .values = gpr13_rx_eq,
474 .num_values = ARRAY_SIZE(gpr13_rx_eq),
475 .def_value = IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB,
476 }, {
477 .name = "fsl,no-spread-spectrum",
478 .def_value = IMX6Q_GPR13_SATA_MPLL_SS_EN,
479 .set_value = 0,
480 },
481};
482
483static u32 imx_ahci_parse_props(struct device *dev,
484 const struct reg_property *prop, size_t num)
485{
486 struct device_node *np = dev->of_node;
487 u32 reg_value = 0;
488 int i, j;
489
490 for (i = 0; i < num; i++, prop++) {
491 u32 of_val;
492
493 if (prop->num_values == 0) {
494 if (of_property_read_bool(np, prop->name))
495 reg_value |= prop->set_value;
496 else
497 reg_value |= prop->def_value;
498 continue;
499 }
500
501 if (of_property_read_u32(np, prop->name, &of_val)) {
502 dev_info(dev, "%s not specified, using %08x\n",
503 prop->name, prop->def_value);
504 reg_value |= prop->def_value;
505 continue;
506 }
507
508 for (j = 0; j < prop->num_values; j++) {
509 if (prop->values[j].of_value == of_val) {
510 dev_info(dev, "%s value %u, using %08x\n",
511 prop->name, of_val, prop->values[j].reg_value);
512 reg_value |= prop->values[j].reg_value;
513 break;
514 }
515 }
516
517 if (j == prop->num_values) {
518 dev_err(dev, "DT property %s is not a valid value\n",
519 prop->name);
520 reg_value |= prop->def_value;
521 }
522 }
523
524 return reg_value;
525}
526
372static int imx_ahci_probe(struct platform_device *pdev) 527static int imx_ahci_probe(struct platform_device *pdev)
373{ 528{
374 struct device *dev = &pdev->dev; 529 struct device *dev = &pdev->dev;
@@ -410,6 +565,8 @@ static int imx_ahci_probe(struct platform_device *pdev)
410 } 565 }
411 566
412 if (imxpriv->type == AHCI_IMX6Q) { 567 if (imxpriv->type == AHCI_IMX6Q) {
568 u32 reg_value;
569
413 imxpriv->gpr = syscon_regmap_lookup_by_compatible( 570 imxpriv->gpr = syscon_regmap_lookup_by_compatible(
414 "fsl,imx6q-iomuxc-gpr"); 571 "fsl,imx6q-iomuxc-gpr");
415 if (IS_ERR(imxpriv->gpr)) { 572 if (IS_ERR(imxpriv->gpr)) {
@@ -417,6 +574,15 @@ static int imx_ahci_probe(struct platform_device *pdev)
417 "failed to find fsl,imx6q-iomux-gpr regmap\n"); 574 "failed to find fsl,imx6q-iomux-gpr regmap\n");
418 return PTR_ERR(imxpriv->gpr); 575 return PTR_ERR(imxpriv->gpr);
419 } 576 }
577
578 reg_value = imx_ahci_parse_props(dev, gpr13_props,
579 ARRAY_SIZE(gpr13_props));
580
581 imxpriv->phy_params =
582 IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M |
583 IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F |
584 IMX6Q_GPR13_SATA_SPD_MODE_3P0G |
585 reg_value;
420 } 586 }
421 587
422 hpriv = ahci_platform_get_resources(pdev); 588 hpriv = ahci_platform_get_resources(pdev);
@@ -454,8 +620,7 @@ static int imx_ahci_probe(struct platform_device *pdev)
454 reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000; 620 reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
455 writel(reg_val, hpriv->mmio + IMX_TIMER1MS); 621 writel(reg_val, hpriv->mmio + IMX_TIMER1MS);
456 622
457 ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info, 623 ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info);
458 0, 0, 0);
459 if (ret) 624 if (ret)
460 goto disable_sata; 625 goto disable_sata;
461 626